Sadržaj

1. Općenito o R-u

2. Rstudio

3. Paketi i Tidyverse

4. Data science proccess

5. Dohvat podataka

6. Priprema podataka

7. Analiza i komunikacija

8. Sljedeći koraci

1. Općenito o R-u

NAPOMENA! Sve što ću danas pričati vrijedi i za druge programske jezike i mislim da se sve ove funkcionalnosti mogu naći i u drugim jezicima, R je samo moj program odabira na kojem sam se učio raditi analitiku, cilj ove prezentacije nije R kao jezik nego stvari koje se mogu općenito raditi u programskim jezicima. U trenutku pisanja R je prema TIOBE indeksu 13. na ljestvici najpopularnijih jezika.

R je besplatan programski jezik koji su u 90-ima osmislili Ross Ihaka i Robert Gentleman iz Novog Zelanda link na wikipedia stranicu. Ono što je važno napomenuti da je R open source jezik i kao takav je besplatan i stalno se razvija jer ima vrlo aktivnu zajednicu.


R se može besplatno skinuti i instalirati ovdje. Instalacija je vrlo jednostavna (next -> next -> next). Kada se instalira, onda se na desktopu stvori ikoan preko koje se pokreće:

Kada se RGui aplikacija pokrene, sučelje izgleda ovako:

2. Rstudio

Većina ljudi kada govori o R-u, zapravo misli na Rstudio sučelje koje se može skinuti i instalirati ovdje. Rstudio koje privatna kompanija koja za sebe kaže sljedeće:

RStudio’s mission is to create free and open-source software for data science, scientific research, and technical communication. We do this to enhance the production and consumption of knowledge by everyone, regardless of economic means, and to facilitate collaboration and reproducible research, both of which are critical to the integrity and efficacy of work in science, education, government, and industry.

Nakon što instaliramo i pokrenemo Rstudio, sučelje izgleda ovako:

Mrkli mrak, zar ne? :)

Što se funkcionalnosti, sve što može Rstudio, može i RGui, no ono u čemu Rstudio prednjači je korisničko iskustvo. Neke od cool funkcionalnosti koje su dostupne u Rstudiju su:

3. Paketi i Tidyverse

Ono što R i slične programe čini izuzetno moćnima je sposobnost podizanja parametrizacije na nekoliko razina apstrakcije.

Najpoznatiji “svemir” aplikacija koje su međusobno konzistentne i međusobno “komuniciraju” je Tidyverse koji razvija upravo Rstudio ekipa:

Popratni materijali vezano za sve pakete u sklopu Tydiversea mogu se pronaći ovdje, pri čemu za ove najvažnije pakete postoje fora šalabahteri. Osim šalabahtera postoje i online knjige, te čak i webinari.

Naravno da ovo nije cijeli “svemir” R paketa, koji trenutno broji preko 15000 paketa.

4. Data science proccess

Proces svake kvantitativne analize se sastoji od 3 ključna dijela i kod sva 3 dijela R nudi vrhunska rješenja.

5. Povezivanje s izvorima podataka

5.1. ECB

ECB ima jako dobro osmišljen sustav skladišta podataka gdje je svaki podatak jednoznačno određen sa jedinstvenim kodom - primjer CLIFS indikatora za HR link:

CLIFS.M.HR._Z.4F.EC.CLIFS_CI.IDX

library(ecb)
library(tidyverse)
library(lubridate)
pom <- get_data("CLIFS.M.._Z.4F.EC.CLIFS_CI.IDX") %>% select(ref_area,obstime,obsvalue) %>% mutate(datum = make_date(ifelse(substr(obstime,6,7)=="12",as.numeric(substr(obstime,1,4))+1,as.numeric(substr(obstime,1,4))), ifelse(substr(obstime,6,7)=="12",1,as.numeric(substr(obstime,6,7))+1), 1)-1) 
ggplot(pom,aes(x=datum,y=obsvalue)) + geom_line() + facet_wrap(~ref_area)

reg = data.frame(ref_area=c("AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","GB","U2","I8"),country=c("Austria","Belgium","Bulgaria","Croatia","Cyprus","Czech Republic","Denmark","Estonia","Finland","France","Germany","Greece","Hungary","Ireland","Italy","Latvia","Lithuania","Luxembourg","Malta","Netherlands","Poland","Portugal","Romania","Slovak Republic","Slovenia","Spain","Sweden","Great Britain","EA changing comp.","Euro Area 19"),regija=c("Other EU","Other EU","CEE","HR","Other EU","CEE","Other EU","CEE","Other EU","Other EU","Other EU","Other EU","CEE","Other EU","Other EU","CEE","CEE","Other EU","Other EU","Other EU","CEE","Other EU","CEE","CEE","CEE","Other EU","Other EU","Other EU","EA changing comp.","Euro Area 19"))
pom <- pom %>% left_join(reg,by="ref_area") %>% group_by(datum,regija) %>% summarise(clifs=mean(obsvalue,na.rm=T))
Column `ref_area` joining character vector and factor, coercing into character vector
ggplot(pom,aes(x=datum,y=clifs,col=regija)) + geom_line() + theme(legend.title = element_blank(),legend.position = "top") + labs(x="",y="CLIFS indeks")

rm(pom)

5.2. Eurostat

Eurostat isto ima svoj paket za pristup R-a na njihovo skladište podataka. Kod njih je pristup malo drukčije organiziran, tako da najprije treba specificirati tablicu na koju se spajamo - primjer za BDP.

library(eurostat)
# 1.1. YOY stopa rasta BDP-a
pom1 <- get_eurostat(id="namq_10_gdp") %>% filter(geo=="HR" & na_item=="B1GQ" & s_adj=="NSA" & unit=="CLV10_MNAC") %>% select(time,bdp=values) %>% arrange(time) %>% as.data.frame()
trying URL 'https://ec.europa.eu/eurostat/estat-navtree-portlet-prod/BulkDownloadListing?sort=1&file=data%2Fnamq_10_gdp.tsv.gz'
Content type 'application/octet-stream;charset=UTF-8' length 13884763 bytes (13.2 MB)
downloaded 13.2 MB
# 1.2. Doprinos - potrošnja kućanstava
pom2 <- get_eurostat(id="namq_10_gdp") %>% filter(geo=="HR" & na_item=="P31_S14_S15" & s_adj=="NSA" & unit=="CLV10_MNAC") %>% select(time,c_hh=values) %>% arrange(time)

# 1.3. Doprinos - potrošnja države
pom3 <- get_eurostat(id="namq_10_gdp") %>% filter(geo=="HR" & na_item=="P3_S13" & s_adj=="NSA" & unit=="CLV10_MNAC") %>% select(time,c_govt=values) %>% arrange(time)

# 1.4. Doprinos - bruto investicije
pom4 <- get_eurostat(id="namq_10_gdp") %>% filter(geo=="HR" & na_item=="P5G" & s_adj=="NSA" & unit=="CLV10_MNAC") %>% select(time,i_gross=values) %>% arrange(time)

# 1.5. Doprinos - izvoz robe i usluga
pom5 <- get_eurostat(id="namq_10_gdp") %>% filter(geo=="HR" & na_item=="P6" & s_adj=="NSA" & unit=="CLV10_MNAC") %>% select(time,ex=values) %>% arrange(time)

# 1.6. Doprinos - uvoz robe i usluga
pom6 <- get_eurostat(id="namq_10_gdp") %>% filter(geo=="HR" & na_item=="P7" & s_adj=="NSA" & unit=="CLV10_MNAC") %>% select(time,im=values) %>% arrange(time)

# opcija 1 - uvijek gledamo godišnje BDP-ove
pom <- left_join(pom1,pom2,by="time") %>% left_join(pom3,by="time") %>% left_join(pom4,by="time") %>% left_join(pom5,by="time") %>% left_join(pom6,by="time") %>% mutate(datum = make_date(ifelse(month(time)>=10,year(time)+1,year(time)),ifelse(month(time)>=10,1,month(time)+3),1) - 1, bdp_y = (bdp + lag(bdp,1)+ lag(bdp,2) + lag(bdp,3))*1000000 , c_hh_y = (c_hh + lag(c_hh,1)+ lag(c_hh,2) + lag(c_hh,3))*1000000 , c_govt_y = (c_govt + lag(c_govt,1)+ lag(c_govt,2) + lag(c_govt,3))*1000000 , i_gross_y = (i_gross + lag(i_gross,1)+ lag(i_gross,2) + lag(i_gross,3))*1000000 , ex_y = (ex + lag(ex,1)+ lag(ex,2) + lag(ex,3))*1000000 , im_y = (im + lag(im,1)+ lag(im,2) + lag(im,3))*1000000) %>% mutate(dbdp = (bdp_y/lag(bdp_y,4)-1)*100 , dop_c_hh = (c_hh_y/lag(c_hh_y,4)-1)*100*lag(c_hh_y,4)/lag(bdp_y,4) , dop_c_govt = (c_govt_y/lag(c_govt_y,4)-1)*100*lag(c_govt_y,4)/lag(bdp_y,4) , dop_i_gross = (i_gross_y/lag(i_gross_y,4)-1)*100*lag(i_gross_y,4)/lag(bdp_y,4) , dop_ex = (ex_y/lag(ex_y,4)-1)*100*lag(ex_y,4)/lag(bdp_y,4) , dop_im = -(im_y/lag(im_y,4)-1)*100*lag(im_y,4)/lag(bdp_y,4)) %>% select(datum,dbdp,dop_c_hh,dop_c_govt,dop_i_gross,dop_ex,dop_im) %>% na.omit()
colnames(pom) <- c("datum","BDP","Potrošnja kućanstava","Javna potrošnja","Bruto investicije","Izvoz","Uvoz")
pom <- pom %>% gather(key = "varijabla",value = "iznos",-datum)
ggplot(pom %>% filter(varijabla!="BDP"),aes(x=datum,y=iznos,fill=varijabla)) + geom_col(position="stack") + geom_point(data=pom %>% filter(varijabla=="BDP"),aes(x=datum,y=iznos)) + theme(legend.position = "top", legend.title = element_blank()) + labs(x="",y="")

rm(pom1,pom2,pom3,pom4,pom5,pom6,pom)

5.3. Svjetska Banka

Kod njih pristup podacima funkcionira na sličan način kao i kod ECB-a, gdje svaki indikator ima jedinstveni kod - primjer za indikator trgovine na tržištu kapitala u %BDP-a.

library(wbstats)
reg = data.frame(ctry=c("AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","GB","U2","I8"),country=c("Austria","Belgium","Bulgaria","Croatia","Cyprus","Czech Republic","Denmark","Estonia","Finland","France","Germany","Greece","Hungary","Ireland","Italy","Latvia","Lithuania","Luxembourg","Malta","Netherlands","Poland","Portugal","Romania","Slovak Republic","Slovenia","Spain","Sweden","Great Britain","EA changing comp.","Euro Area 19"),regija=c("Other EU","Other EU","CEE","HR","Other EU","CEE","Other EU","CEE","Other EU","Other EU","Other EU","Other EU","CEE","Other EU","Other EU","CEE","CEE","Other EU","Other EU","Other EU","CEE","Other EU","CEE","CEE","CEE","Other EU","Other EU","Other EU","EA changing comp.","Euro Area 19"))
stocks_traded <- wb(indicator = "CM.MKT.TRAD.GD.ZS")
pom <- stocks_traded %>% filter(iso2c %in% reg$ctry & date %in% c("2014","2015","2016","2017","2018")) %>% select(date,ctry=iso2c,value) %>% group_by(ctry) %>% summarise(value=mean(value,na.rm=T)) %>% left_join(reg,by="ctry") %>% filter(ctry!="US") %>% mutate(regija=ifelse(regija=="CEE","Zemlje SIE",ifelse(regija=="Other EU","Ostale EU zemlje","HR")))
Column `ctry` joining character vector and factor, coercing into character vector
ggplot(pom,aes(x=reorder(ctry,-value),y=value)) + geom_col(aes(fill=regija)) + labs(x="",y="") + theme(legend.position="top",legend.title = element_blank())

rm(reg,stocks_traded,pom)

5.4. OECD

Jedan fora primjer mogućnosti R-a, su rezultati financijske pismenosti koju provodi OECD i koju objalvjuje u PDF-u. Postoji paket u R-u koji ima spoobnost čitanja PDF-ova i uspio je učitati ove podatke sa slike na stranici 10.

library(tabulizer)
pismenost_tablica <- extract_tables("http://www.oecd.org/daf/fin/financial-education/OECD-INFE-International-Survey-of-Adult-Financial-Literacy-Competencies.pdf")
temp <- pismenost_tablica[[3]]
temp <- as.data.frame(temp)
colnames(temp)<-c("ctry_score","knowledge_score","behaviour_score","attitude_score")
temp <- temp %>% separate(ctry_score,c("country","financial_knowledge")," \\(") %>% mutate(financial_knowledge=str_replace(financial_knowledge,"\\)","")) %>% mutate(financial_knowledge=as.numeric(financial_knowledge),knowledge_score=as.character(knowledge_score),behaviour_score=as.character(behaviour_score),attitude_score=as.character(attitude_score)) %>% mutate(knowledge_score=as.numeric(knowledge_score),behaviour_score=as.numeric(behaviour_score),attitude_score=as.numeric(attitude_score))
financijska_pismenost <- temp
reg = data.frame(ctry=c("AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","GB","U2","US"),country=c("Austria","Belgium","Bulgaria","Croatia","Cyprus","Czech Republic","Denmark","Estonia","Finland","France","Germany","Greece","Hungary","Ireland","Italy","Latvia","Lithuania","Luxembourg","Malta","Netherlands","Poland","Portugal","Romania","Slovak Republic","Slovenia","Spain","Sweden","United Kingdom","EA changing comp.","United States"),regija=c("Other EU","Other EU","CEE","HR","Other EU","CEE","Other EU","CEE","Other EU","Other EU","Other EU","Other EU","CEE","Other EU","Other EU","CEE","CEE","Other EU","Other EU","Other EU","CEE","Other EU","CEE","CEE","CEE","Other EU","Other EU","Other EU","EA changing comp.","US"))
pom <- financijska_pismenost %>% filter(country %in% reg$country) %>% left_join(reg,by="country")
Column `country` joining character vector and factor, coercing into character vector
ggplot(pom,aes(x=reorder(ctry,-financial_knowledge),y=financial_knowledge)) + geom_col(aes(fill=regija)) + geom_hline(yintercept = financijska_pismenost$financial_knowledge[financijska_pismenost$country=="Average, all countries"]) + labs(x="",y="Financijska pismenost") + theme(legend.position="top")

rm(pismenost_tablica,temp,financijska_pismenost,pom)

5.5. EIOPA podaci

EIOPA nije napredna kao ECB ili EUROSTAT u objavi podataka i objavljuje ih u excelima, no i za to imamo sistem.

skripta EIOPA_dohvat_podataka.R

6. Priprema podataka

Važno je naglasiti da je za kvalitetnu analizu nužna dobra priprema podataka. Prema istraživanju CrowdFlower-a, u Data science-u se 80% vremena svodi na pripremu podataka, što je ujedno i najmanje zanimljiv dio procesa.

6.1. Tidy struktura podataka

Kako bi se vrijeme potrebno za obradu podataka, ali i vrijeme za analizu podataka smanjilo, nužno je da podaci budu u tidy formatu.

6.2. Financijski računi

Financijske račune dobivamo na krajnje nestrukturiran način i koji se nalaze ovdje. Ono što R omogućuje je sklapanje u 1 bazu koja se onda može koristiti za analizu i ne samo to nego je na taj način 970MB podataka u excelima pretvoreno u 2.7MB veliki dataframe.

folder Financijski_racuni

Ovakva struktura podataka omogućuje sljedeće slike:

# brisanje privremenih tablica
rm(zadnji_datum,br_dana,pom1,pom2,pom3,pom4,pom,bridovi,vrhovi,graf,financijski_racuni)
object 'zadnji_datum' not foundobject 'br_dana' not foundobject 'pom1' not foundobject 'pom2' not foundobject 'pom3' not foundobject 'pom4' not foundobject 'pom' not foundobject 'bridovi' not foundobject 'vrhovi' not foundobject 'graf' not found

6.3. Shiny aplikacija

Kada su podaci u tidy formatu, onda je moguće napraviti sljedeću aplikaciju za analizu kretanja u sustavu.

folder Shiny bilanca

7. Analiza i komunikacija rezultata

7.1. Plotly

Ovo je primjer Gantt-grafikona koji ste vidjeli prošli tjedan sa vremenskim planom aktivnosti oko pripreme 4. broja Makroprudencijalnog skenera rizika.

skripta gantt_skener4.R

7.2. Gapminder primjer

Hans Rosling je jedno od najpoznatijih imena u statističkim krugovima i veliki popularizator “data sciencea”, njegov TED talk je jedan od najgledanijih ikada (velika preporuka da ga pogledate).

skripta gapminder primjer.R

7.3. Shiny mreže OeNB-a

folder JVI_Contagion

7.4. Mapa EU

Vrlo jednostavno se može napraviti i mapa EU po zemljama. Npr, prikaz definicije regija koje prikazujemo u skeneru.

library(tidyverse)
library(grid)
library(rworldmap)
package 㤼㸱rworldmap㤼㸲 was built under R version 3.6.2Loading required package: sp
### Welcome to rworldmap ###
For a short introduction type :      vignette('rworldmap')
library(eurostat)
library(lubridate)

# Get the world map
worldMap <- getMap()

# Member States of the European Union
reg = data.frame(ref_area=c("AT","BE","BG","HR","CY","CZ","DK","EE","FI","FR","DE","GR","HU","IE","IT","LV","LT","LU","MT","NL","PL","PT","RO","SK","SI","ES","SE","GB"),country=c("Austria","Belgium","Bulgaria","Croatia","Cyprus","Czech Rep.","Denmark","Estonia","Finland","France","Germany","Greece","Hungary","Ireland","Italy","Latvia","Lithuania","Luxembourg","Malta","Netherlands","Poland","Portugal","Romania","Slovakia","Slovenia","Spain","Sweden","United Kingdom"),regija=c("Other EU","Other EU","CEE","HR","Other EU","CEE","Other EU","CEE","Other EU","Other EU","Other EU","Other EU","CEE","Other EU","Other EU","CEE","CEE","Other EU","Other EU","Other EU","CEE","Other EU","CEE","CEE","CEE","Other EU","Other EU","Other EU"))

# Select only the index of states member of the E.U.
indEU <- which(worldMap$NAME %in% reg$country)

# Extract longitude and latitude border's coordinates of members states of E.U. 
europeCoords <- lapply(indEU, function(i){
  df <- data.frame(worldMap@polygons[[i]]@Polygons[[1]]@coords)
  df$region =as.character(worldMap$NAME[i])
  colnames(df) <- list("long", "lat", "region")
  return(df)
})

europeCoords <- do.call("rbind", europeCoords)

# 1. Mapa regija ####
europeanUnionTable <- data.frame(country = reg$country, value = reg$regija)
europeCoords$value <- europeanUnionTable$value[match(europeCoords$region,europeanUnionTable$country)]

# Plot the map
P <- ggplot() + geom_polygon(data = europeCoords, aes(x = long, y = lat, group = region, fill = value), colour = "black", size = 0.1) + coord_map(xlim = c(-13, 35),  ylim = c(32, 71))
P <- P + scale_fill_discrete(name = "Regija", na.value = "grey50")
P <- P + theme(#panel.grid.minor = element_line(colour = NA), panel.grid.minor = element_line(colour = NA),
  #panel.background = element_rect(fill = NA, colour = NA),
  axis.text.x = element_blank(),
  axis.text.y = element_blank(), axis.ticks.x = element_blank(),
  axis.ticks.y = element_blank(), axis.title = element_blank(),
  #rect = element_blank(),
  plot.margin = unit(0 * c(-1.5, -1.5, -1.5, -1.5), "lines"))
P


P <- P + scale_fill_gradient(name = "Growth Rate", low = "#FF0000FF", high = "#FFFF00FF", na.value = "grey50")
Scale for 'fill' is already present. Adding another scale for 'fill', which will replace the existing scale.

Jednako jednostavno se može napraviti i kontinuirana mapa koja npr. prikazuje kumulativni rast BDP-a od 2010. po EU zemljama.

pom <- get_eurostat(id="namq_10_gdp") %>% filter(na_item=="B1GQ" & s_adj=="NSA" & unit=="CLV10_MNAC") %>% select(time,geo,bdp=values) %>% arrange(time) %>% as.data.frame() %>% group_by(geo) %>% mutate(bdp_y = (bdp + lag(bdp,1)+ lag(bdp,2) + lag(bdp,3))) %>% filter(time>="2007-10-01") %>% mutate(datum = make_date(ifelse(month(time)>=10,year(time)+1,year(time)),ifelse(month(time)>=10,1,month(time)+3),1) - 1) %>% select(datum,ref_area=geo,bdp_y) %>% na.omit() %>% ungroup()
Reading cache file C:\Users\MBAMBU~1\AppData\Local\Temp\RtmpIB6cQg/eurostat/namq_10_gdp_date_code_TF.rds
Table  namq_10_gdp  read from cache file:  C:\Users\MBAMBU~1\AppData\Local\Temp\RtmpIB6cQg/eurostat/namq_10_gdp_date_code_TF.rds
baza <- pom %>% filter(datum=="2010-12-31") %>% select(ref_area,baza=bdp_y)
delta_bdp <- left_join(pom,baza,by=c("ref_area")) %>% mutate(indeks=bdp_y/baza*100) %>% filter(datum=="2019-09-30") %>% left_join(reg,by="ref_area") %>% na.omit()
Column `ref_area` joining factors with different levels, coercing to character vector
europeanUnionTable <- data.frame(country = delta_bdp$country, value = delta_bdp$indeks)
europeCoords$value <- europeanUnionTable$value[match(europeCoords$region,europeanUnionTable$country)]

# Plot the map
P <- ggplot() + geom_polygon(data = europeCoords, aes(x = long, y = lat, group = region, fill = value), colour = "black", size = 0.1) + coord_map(xlim = c(-13, 35),  ylim = c(32, 71))
P <- P + scale_fill_gradient(name = "Kumulativni rast BDP-a od 2010.", low = "red", high = "green", na.value = "grey50")
P <- P + theme(#panel.grid.minor = element_line(colour = NA), panel.grid.minor = element_line(colour = NA),
  #panel.background = element_rect(fill = NA, colour = NA),
  axis.text.x = element_blank(),
  axis.text.y = element_blank(), axis.ticks.x = element_blank(),
  axis.ticks.y = element_blank(), axis.title = element_blank(),
  #rect = element_blank(),
  plot.margin = unit(0 * c(-1.5, -1.5, -1.5, -1.5), "lines"))
P

# brisanje privremenih tablica
rm(worldMap,reg,indEU,europeCoords,europeanUnionTable,P,pom,baza,delta_bdp)

7.5. Word cloud riječi koje su se najčešće koristile u 3. broju skenera

skripta word_cloud.R

8. Sljedeći koraci

Do sada nije bilo puno govora o in-house podacima. To je još work in progress. Ako nekoga zanima, ovako izgleda struktura skladišta podataka. Pri čemu svaki od navedenih čvorova je jedna vrsta iznosa koji se pohranjuje u bazi ima svoja pravila. Taj gordijski čvor ćemo morati raspetljati i pripremiti podatke (odraditi onih 80% posla) tako da možemo pristupiti analizi na kvalitetan način.

library(tidyverse)
library(lubridate)
library(readxl)

# Funkcija za kopiranje u excel ####
skopiraj <- function(x,row.names=FALSE,col.names=TRUE,...) {
  write.table(x,"clipboard",sep="\t",row.names=row.names,col.names=col.names,...)
}

load("finpodaci.Rda")

# 0. Popis obrazaca, izvještaja, redaka i stupaca ####
#popis <- finpodaci %>% select(sektor,izvjestaj,obrazac,oznaka_obrasca,oznaka_retka,redak,stupac,stupac_naziv) %>% distinct()

# 1. Osiguranja - bilanca ####
os_bilanca <- finpodaci %>% filter(izvjestaj %in% c("TIDO","TIDRE","TIDO-RE") & oznaka_obrasca=="Standardno" & obrazac %in% c("Bilanca","IFP") & stupac_naziv %in% c("TIDO - Bilanca - Tekuća godina - Život","TIDO - Bilanca - Tekuća godina - Neživot ","TIDRE - Bilanca - Tekuća godina - Život","TIDRE - Bilanca - Tekuća godina - Neživot ","TIDO-RE - IFP - Tekuća godina - Neživot ","TIDO-RE - IFP - Tekuća godina - Život")) %>% unite("obrazac",izvjestaj,obrazac,sep="-") %>% unite("redak",oznaka_retka,redak,sep=".") %>% select(datum,vrsta=stupac,subjekt,obrazac,redak,iznos) %>% mutate(vrsta=str_trim(vrsta),redak=str_trim(redak))
# uvoz razina iz excela
razine <- read_excel("Mapiranje obrazaca - osiguranja.xlsx",sheet = "za_izvoz_bilanca")
os_bilanca <- full_join(os_bilanca,razine,by=c("obrazac","redak")) %>% na.omit()

# Struktura imovine
pom <- os_bilanca %>% group_by(datum,razina2) %>% filter(datum>="2011-09-30" & razina1=="Imovina") %>% summarise(iznos=sum(iznos,na.rm=T)/1000000000)
ggplot(pom,aes(x=datum,y=iznos,fill=razina2)) + geom_area() + ggtitle("Imovina") + theme(legend.position = "top") + theme(legend.position = "top") + labs(x="",y="mlrd. HRK")

# Struktura ulaganja
pom <- os_bilanca %>% group_by(datum,razina3) %>% filter(datum>="2011-09-30" & razina2=="Ulaganja") %>% summarise(iznos=sum(iznos,na.rm=T)/1000000000)
ggplot(pom,aes(x=datum,y=iznos,fill=razina3)) + geom_area() + ggtitle("Ulaganja") + theme(legend.position = "top") + theme(legend.position = "top") + labs(x="",y="mlrd. HRK")

# Struktura obveza
pom <- os_bilanca %>% group_by(datum,razina2) %>% filter(datum>="2011-09-30" & razina1=="Obveze") %>% summarise(iznos=sum(iznos,na.rm=T)/1000000000)
ggplot(pom,aes(x=datum,y=iznos,fill=razina2)) + geom_area() + ggtitle("Obveze") + theme(legend.position = "top") + theme(legend.position = "top") + labs(x="",y="mlrd. HRK")

# Struktura tehničkih pričuva
pom <- os_bilanca %>% group_by(datum,razina3) %>% filter(datum>="2011-09-30" & razina2=="Tehničke pričuve") %>% summarise(iznos=sum(iznos,na.rm=T)/1000000000)
ggplot(pom,aes(x=datum,y=iznos,fill=razina3)) + geom_area() + ggtitle("Tehničke pričuve") + theme(legend.position = "top") + labs(x="",y="mlrd. HRK")

# brisanje privremenih tablica
rm(finpodaci,os_bilanca,pom,razine)
LS0tDQp0aXRsZTogIlV2b2QgdSBSIg0KYXV0aG9yOiAiTWFyaW8gQmFtYnVsb3ZpxIciDQpkYXRlOiAiMTQuMi4yMDIwLiINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMjIFNhZHLFvmFqDQoNCiMjIyMgMS4gT3DEh2VuaXRvIG8gUi11DQojIyMjIDIuIFJzdHVkaW8NCiMjIyMgMy4gUGFrZXRpIGkgVGlkeXZlcnNlDQojIyMjIDQuIERhdGEgc2NpZW5jZSBwcm9jY2Vzcw0KIyMjIyA1LiBEb2h2YXQgcG9kYXRha2ENCiMjIyMgNi4gUHJpcHJlbWEgcG9kYXRha2ENCiMjIyMgNy4gQW5hbGl6YSBpIGtvbXVuaWthY2lqYQ0KIyMjIyA4LiBTbGplZGXEh2kga29yYWNpDQoNCiMjIDEuIE9wxIdlbml0byBvIFItdQ0KDQoqKk5BUE9NRU5BISBTdmUgxaF0byDEh3UgZGFuYXMgcHJpxI1hdGkgdnJpamVkaSBpIHphIGRydWdlIHByb2dyYW1za2UgamV6aWtlIGkgbWlzbGltIGRhIHNlIHN2ZSBvdmUgZnVua2Npb25hbG5vc3RpIG1vZ3UgbmHEh2kgaSB1IGRydWdpbSBqZXppY2ltYSwgUiBqZSBzYW1vIG1vaiBwcm9ncmFtIG9kYWJpcmEgbmEga29qZW0gc2FtIHNlIHXEjWlvIHJhZGl0aSBhbmFsaXRpa3UsIGNpbGogIG92ZSBwcmV6ZW50YWNpamUgbmlqZSBSIGthbyBqZXppayBuZWdvIHN0dmFyaSBrb2plIHNlIG1vZ3Ugb3DEh2VuaXRvIHJhZGl0aSB1IHByb2dyYW1za2ltIGplemljaW1hLiBVIHRyZW51dGt1IHBpc2FuamEgUiBqZSBwcmVtYSBbVElPQkUgaW5kZWtzdV0oaHR0cHM6Ly93d3cudGlvYmUuY29tL3Rpb2JlLWluZGV4LykgMTMuIG5hIGxqZXN0dmljaSBuYWpwb3B1bGFybmlqaWggamV6aWthLioqDQoNClIgamUgYmVzcGxhdGFuIHByb2dyYW1za2kgamV6aWsga29qaSBzdSB1IDkwLWltYSBvc21pc2xpbGkgUm9zcyBJaGFrYSBpIFJvYmVydCBHZW50bGVtYW4gaXogTm92b2cgWmVsYW5kYSBbbGluayBuYSB3aWtpcGVkaWEgc3RyYW5pY3VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1JfKHByb2dyYW1taW5nX2xhbmd1YWdlKSkuIE9ubyDFoXRvIGplIHZhxb5ubyBuYXBvbWVudXRpIGRhIGplIFIgKipvcGVuIHNvdXJjZSBqZXppayoqIGkga2FvIHRha2F2IGplICoqYmVzcGxhdGFuKiogaSBzdGFsbm8gc2UgcmF6dmlqYSBqZXIgaW1hIHZybG8gYWt0aXZudSB6YWplZG5pY3UuDQoNCiAhW10ob3NuaXZhxI1pLlBORykgDQoNCioqKg0KDQpSIHNlIG1vxb5lIGJlc3BsYXRubyBza2ludXRpIGkgaW5zdGFsaXJhdGkgW292ZGplXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy9iaW4vd2luZG93cy9iYXNlLykuIEluc3RhbGFjaWphIGplIHZybG8gamVkbm9zdGF2bmEgKG5leHQgLT4gbmV4dCAtPiBuZXh0KS4gS2FkYSBzZSBpbnN0YWxpcmEsIG9uZGEgc2UgbmEgZGVza3RvcHUgc3R2b3JpIGlrb2FuIHByZWtvIGtvamUgc2UgcG9rcmXEh2U6DQoNCiFbXShSZ3VpX2lrb25hLlBORykNCg0KS2FkYSBzZSBSR3VpIGFwbGlrYWNpamEgcG9rcmVuZSwgc3XEjWVsamUgaXpnbGVkYSBvdmFrbzoNCg0KIVtdKFJndWkuUE5HKQ0KDQoNCiMjIDIuIFJzdHVkaW8NCg0KVmXEh2luYSBsanVkaSBrYWRhIGdvdm9yaSBvIFItdSwgemFwcmF2byBtaXNsaSBuYSBSc3R1ZGlvIHN1xI1lbGplIGtvamUgc2UgbW/FvmUgc2tpbnV0aSBpIGluc3RhbGlyYXRpIFtvdmRqZV0oaHR0cHM6Ly9yc3R1ZGlvLmNvbS8pLiBSc3R1ZGlvIGtvamUgcHJpdmF0bmEga29tcGFuaWphIGtvamEgemEgc2ViZSBrYcW+ZSBzbGplZGXEh2U6IA0KDQo+IFJTdHVkaW8ncyBtaXNzaW9uIGlzIHRvIGNyZWF0ZSBmcmVlIGFuZCBvcGVuLXNvdXJjZSBzb2Z0d2FyZSBmb3IgZGF0YSBzY2llbmNlLCBzY2llbnRpZmljIHJlc2VhcmNoLCBhbmQgdGVjaG5pY2FsIGNvbW11bmljYXRpb24uIFdlIGRvIHRoaXMgdG8gZW5oYW5jZSB0aGUgcHJvZHVjdGlvbiBhbmQgY29uc3VtcHRpb24gb2Yga25vd2xlZGdlIGJ5IGV2ZXJ5b25lLCByZWdhcmRsZXNzIG9mIGVjb25vbWljIG1lYW5zLCBhbmQgdG8gZmFjaWxpdGF0ZSBjb2xsYWJvcmF0aW9uIGFuZCByZXByb2R1Y2libGUgcmVzZWFyY2gsIGJvdGggb2Ygd2hpY2ggYXJlIGNyaXRpY2FsIHRvIHRoZSBpbnRlZ3JpdHkgYW5kIGVmZmljYWN5IG9mIHdvcmsgaW4gc2NpZW5jZSwgZWR1Y2F0aW9uLCBnb3Zlcm5tZW50LCBhbmQgaW5kdXN0cnkuDQoNCk5ha29uIMWhdG8gaW5zdGFsaXJhbW8gaSBwb2tyZW5lbW8gUnN0dWRpbywgc3XEjWVsamUgaXpnbGVkYSBvdmFrbzoNCg0KIVtdKFJzdHVkaW8uUE5HKQ0KDQoqKk1ya2xpIG1yYWssIHphciBuZT8gOikqKg0KDQrFoHRvIHNlIGZ1bmtjaW9uYWxub3N0aSwgc3ZlIMWhdG8gbW/FvmUgUnN0dWRpbywgbW/FvmUgaSBSR3VpLCBubyBvbm8gdSDEjWVtdSBSc3R1ZGlvIHByZWRuamHEjWkgamUga29yaXNuacSNa28gaXNrdXN0dm8uIE5la2Ugb2QgY29vbCBmdW5rY2lvbmFsbm9zdGkga29qZSBzdSBkb3N0dXBuZSB1IFJzdHVkaWp1IHN1Og0KDQoqIHRhbW5hIHBvemFkaW5hIDopDQoqIHBvdmV6aXZhbmplIHMgR2l0aHViLW9tIChvIHRvbWUgdmnFoWUga2FzbmlqZSkNCiogVmlld2VyDQoqIFJtYXJrZG93bg0KKiBTaGlueQ0KKiBwb21vxIcgcHJpIHBpc2FuanUgKHJhemxpxI1pdGUgYm9qZSB6YSByYXpsacSNaXRlIG9iamVrdGUsIHphdHZhcmFuamUgemFncmFkYSwgYXV0b2NvcnJlY3QsIHN1Z2VyaXJhbmplIHJpamXEjWksIGl0ZC4uLikNCg0KIyMgMy4gUGFrZXRpIGkgVGlkeXZlcnNlDQoNCk9ubyDFoXRvIFIgaSBzbGnEjW5lIHByb2dyYW1lIMSNaW5pIGl6dXpldG5vIG1vxIduaW1hIGplIHNwb3NvYm5vc3QgcG9kaXphbmphIHBhcmFtZXRyaXphY2lqZSBuYSBuZWtvbGlrbyByYXppbmEgYXBzdHJha2NpamUuDQoNCiFbXShQYXJhbWV0cml6YWNpamEuUE5HKQ0KDQpOYWpwb3puYXRpamkgInN2ZW1pciIgYXBsaWthY2lqYSBrb2plIHN1IG1lxJF1c29ibm8ga29uemlzdGVudG5lIGkgbWXEkXVzb2JubyAia29tdW5pY2lyYWp1IiBqZSAqKlRpZHl2ZXJzZSoqIGtvamkgcmF6dmlqYSB1cHJhdm8gUnN0dWRpbyBla2lwYToNCg0KIVtdKFRpZHl2ZXJzZS5QTkcpDQoNClBvcHJhdG5pIG1hdGVyaWphbGkgdmV6YW5vIHphIHN2ZSBwYWtldGUgdSBza2xvcHUgVHlkaXZlcnNlYSBtb2d1IHNlIHByb25hxIdpIFtvdmRqZV0oaHR0cHM6Ly9yc3R1ZGlvLmNvbS9wcm9kdWN0cy9ycGFja2FnZXMvKSwgcHJpIMSNZW11IHphIG92ZSBuYWp2YcW+bmlqZSBwYWtldGUgcG9zdG9qZSBmb3JhIFvFoWFsYWJhaHRlcmldKGh0dHBzOi8vcnN0dWRpby5jb20vcmVzb3VyY2VzL2NoZWF0c2hlZXRzLykuIE9zaW0gxaFhbGFiYWh0ZXJhIHBvc3RvamUgaSBbb25saW5lIGtuamlnZV0oaHR0cHM6Ly9yc3R1ZGlvLmNvbS9yZXNvdXJjZXMvYm9va3MvKSwgdGUgxI1hayBpIFt3ZWJpbmFyaV0oaHR0cHM6Ly9yZXNvdXJjZXMucnN0dWRpby5jb20vKS4NCg0KTmFyYXZubyBkYSBvdm8gbmlqZSBjaWplbGkgInN2ZW1pciIgUiBwYWtldGEsIGtvamkgdHJlbnV0bm8gYnJvamkgcHJla28gWzE1MDAwIHBha2V0YV0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL2NoZWNrcy9jaGVja19zdW1tYXJ5Lmh0bWwpLiANCg0KIyMgNC4gRGF0YSBzY2llbmNlIHByb2NjZXNzDQoNClByb2NlcyBzdmFrZSBrdmFudGl0YXRpdm5lIGFuYWxpemUgc2Ugc2FzdG9qaSBvZCAzIGtsanXEjW5hIGRpamVsYSBpIGtvZCBzdmEgMyBkaWplbGEgUiBudWRpIHZyaHVuc2thIHJqZcWhZW5qYS4NCg0KIVtdKGRhdGFfc2NpZW5jZV9wcm9jZXNzLlBORykNCg0KIyMgNS4gUG92ZXppdmFuamUgcyBpenZvcmltYSBwb2RhdGFrYQ0KDQojIyMgNS4xLiBFQ0INCg0KRUNCIGltYSBqYWtvIGRvYnJvIG9zbWnFoWxqZW4gc3VzdGF2IFtza2xhZGnFoXRhIHBvZGF0YWthXShodHRwOi8vc2R3LmVjYi5ldXJvcGEuZXUvYnJvd3NlLmRvP25vZGU9OTY4OTcyNykgZ2RqZSBqZSBzdmFraSBwb2RhdGFrIGplZG5vem5hxI1ubyBvZHJlxJFlbiBzYSBqZWRpbnN0dmVuaW0ga29kb20gLSBwcmltamVyIENMSUZTIGluZGlrYXRvcmEgemEgSFIgW2xpbmtdKGh0dHA6Ly9zZHcuZWNiLmV1cm9wYS5ldS9icm93c2VTZWxlY3Rpb24uZG8/bm9kZT05NjkzMzQ3KToNCg0KPiBDTElGUy5NLkhSLl9aLjRGLkVDLkNMSUZTX0NJLklEWA0KDQpgYGB7ciB9DQpsaWJyYXJ5KGVjYikNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpwb20gPC0gZ2V0X2RhdGEoIkNMSUZTLk0uLl9aLjRGLkVDLkNMSUZTX0NJLklEWCIpICU+JSBzZWxlY3QocmVmX2FyZWEsb2JzdGltZSxvYnN2YWx1ZSkgJT4lIG11dGF0ZShkYXR1bSA9IG1ha2VfZGF0ZShpZmVsc2Uoc3Vic3RyKG9ic3RpbWUsNiw3KT09IjEyIixhcy5udW1lcmljKHN1YnN0cihvYnN0aW1lLDEsNCkpKzEsYXMubnVtZXJpYyhzdWJzdHIob2JzdGltZSwxLDQpKSksIGlmZWxzZShzdWJzdHIob2JzdGltZSw2LDcpPT0iMTIiLDEsYXMubnVtZXJpYyhzdWJzdHIob2JzdGltZSw2LDcpKSsxKSwgMSktMSkgDQpnZ3Bsb3QocG9tLGFlcyh4PWRhdHVtLHk9b2JzdmFsdWUpKSArIGdlb21fbGluZSgpICsgZmFjZXRfd3JhcCh+cmVmX2FyZWEpDQoNCmBgYA0KDQpgYGB7cn0NCnJlZyA9IGRhdGEuZnJhbWUocmVmX2FyZWE9YygiQVQiLCJCRSIsIkJHIiwiSFIiLCJDWSIsIkNaIiwiREsiLCJFRSIsIkZJIiwiRlIiLCJERSIsIkdSIiwiSFUiLCJJRSIsIklUIiwiTFYiLCJMVCIsIkxVIiwiTVQiLCJOTCIsIlBMIiwiUFQiLCJSTyIsIlNLIiwiU0kiLCJFUyIsIlNFIiwiR0IiLCJVMiIsIkk4IiksY291bnRyeT1jKCJBdXN0cmlhIiwiQmVsZ2l1bSIsIkJ1bGdhcmlhIiwiQ3JvYXRpYSIsIkN5cHJ1cyIsIkN6ZWNoIFJlcHVibGljIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwiR2VybWFueSIsIkdyZWVjZSIsIkh1bmdhcnkiLCJJcmVsYW5kIiwiSXRhbHkiLCJMYXR2aWEiLCJMaXRodWFuaWEiLCJMdXhlbWJvdXJnIiwiTWFsdGEiLCJOZXRoZXJsYW5kcyIsIlBvbGFuZCIsIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3ZhayBSZXB1YmxpYyIsIlNsb3ZlbmlhIiwiU3BhaW4iLCJTd2VkZW4iLCJHcmVhdCBCcml0YWluIiwiRUEgY2hhbmdpbmcgY29tcC4iLCJFdXJvIEFyZWEgMTkiKSxyZWdpamE9YygiT3RoZXIgRVUiLCJPdGhlciBFVSIsIkNFRSIsIkhSIiwiT3RoZXIgRVUiLCJDRUUiLCJPdGhlciBFVSIsIkNFRSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiQ0VFIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIkNFRSIsIkNFRSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIkNFRSIsIk90aGVyIEVVIiwiQ0VFIiwiQ0VFIiwiQ0VFIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiRUEgY2hhbmdpbmcgY29tcC4iLCJFdXJvIEFyZWEgMTkiKSkNCnBvbSA8LSBwb20gJT4lIGxlZnRfam9pbihyZWcsYnk9InJlZl9hcmVhIikgJT4lIGdyb3VwX2J5KGRhdHVtLHJlZ2lqYSkgJT4lIHN1bW1hcmlzZShjbGlmcz1tZWFuKG9ic3ZhbHVlLG5hLnJtPVQpKQ0KZ2dwbG90KHBvbSxhZXMoeD1kYXR1bSx5PWNsaWZzLGNvbD1yZWdpamEpKSArIGdlb21fbGluZSgpICsgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArIGxhYnMoeD0iIix5PSJDTElGUyBpbmRla3MiKQ0Kcm0ocG9tKQ0KYGBgDQoNCiMjIyA1LjIuIEV1cm9zdGF0DQoNCkV1cm9zdGF0IGlzdG8gaW1hIHN2b2ogcGFrZXQgemEgcHJpc3R1cCBSLWEgbmEgbmppaG92byBbc2tsYWRpxaF0ZSBwb2RhdGFrYV0oaHR0cHM6Ly9lYy5ldXJvcGEuZXUvZXVyb3N0YXQvZGF0YS9kYXRhYmFzZSkuIEtvZCBuamloIGplIHByaXN0dXAgbWFsbyBkcnVrxI1pamUgb3JnYW5pemlyYW4sIHRha28gZGEgbmFqcHJpamUgdHJlYmEgc3BlY2lmaWNpcmF0aSB0YWJsaWN1IG5hIGtvanUgc2Ugc3BhamFtbyAtIFtwcmltamVyIHphIEJEUF0oaHR0cHM6Ly9hcHBzc28uZXVyb3N0YXQuZWMuZXVyb3BhLmV1L251aS9zaG93LmRvP2RhdGFzZXQ9bmFtcV8xMF9nZHAmbGFuZz1lbikuDQoNCmBgYHtyLCBtZXNzYWdlPUZ9DQpsaWJyYXJ5KGV1cm9zdGF0KQ0KIyAxLjEuIFlPWSBzdG9wYSByYXN0YSBCRFAtYQ0KcG9tMSA8LSBnZXRfZXVyb3N0YXQoaWQ9Im5hbXFfMTBfZ2RwIikgJT4lIGZpbHRlcihnZW89PSJIUiIgJiBuYV9pdGVtPT0iQjFHUSIgJiBzX2Fkaj09Ik5TQSIgJiB1bml0PT0iQ0xWMTBfTU5BQyIpICU+JSBzZWxlY3QodGltZSxiZHA9dmFsdWVzKSAlPiUgYXJyYW5nZSh0aW1lKSAlPiUgYXMuZGF0YS5mcmFtZSgpDQoNCiMgMS4yLiBEb3ByaW5vcyAtIHBvdHJvxaFuamEga3XEh2Fuc3RhdmENCnBvbTIgPC0gZ2V0X2V1cm9zdGF0KGlkPSJuYW1xXzEwX2dkcCIpICU+JSBmaWx0ZXIoZ2VvPT0iSFIiICYgbmFfaXRlbT09IlAzMV9TMTRfUzE1IiAmIHNfYWRqPT0iTlNBIiAmIHVuaXQ9PSJDTFYxMF9NTkFDIikgJT4lIHNlbGVjdCh0aW1lLGNfaGg9dmFsdWVzKSAlPiUgYXJyYW5nZSh0aW1lKQ0KDQojIDEuMy4gRG9wcmlub3MgLSBwb3Ryb8WhbmphIGRyxb5hdmUNCnBvbTMgPC0gZ2V0X2V1cm9zdGF0KGlkPSJuYW1xXzEwX2dkcCIpICU+JSBmaWx0ZXIoZ2VvPT0iSFIiICYgbmFfaXRlbT09IlAzX1MxMyIgJiBzX2Fkaj09Ik5TQSIgJiB1bml0PT0iQ0xWMTBfTU5BQyIpICU+JSBzZWxlY3QodGltZSxjX2dvdnQ9dmFsdWVzKSAlPiUgYXJyYW5nZSh0aW1lKQ0KDQojIDEuNC4gRG9wcmlub3MgLSBicnV0byBpbnZlc3RpY2lqZQ0KcG9tNCA8LSBnZXRfZXVyb3N0YXQoaWQ9Im5hbXFfMTBfZ2RwIikgJT4lIGZpbHRlcihnZW89PSJIUiIgJiBuYV9pdGVtPT0iUDVHIiAmIHNfYWRqPT0iTlNBIiAmIHVuaXQ9PSJDTFYxMF9NTkFDIikgJT4lIHNlbGVjdCh0aW1lLGlfZ3Jvc3M9dmFsdWVzKSAlPiUgYXJyYW5nZSh0aW1lKQ0KDQojIDEuNS4gRG9wcmlub3MgLSBpenZveiByb2JlIGkgdXNsdWdhDQpwb201IDwtIGdldF9ldXJvc3RhdChpZD0ibmFtcV8xMF9nZHAiKSAlPiUgZmlsdGVyKGdlbz09IkhSIiAmIG5hX2l0ZW09PSJQNiIgJiBzX2Fkaj09Ik5TQSIgJiB1bml0PT0iQ0xWMTBfTU5BQyIpICU+JSBzZWxlY3QodGltZSxleD12YWx1ZXMpICU+JSBhcnJhbmdlKHRpbWUpDQoNCiMgMS42LiBEb3ByaW5vcyAtIHV2b3ogcm9iZSBpIHVzbHVnYQ0KcG9tNiA8LSBnZXRfZXVyb3N0YXQoaWQ9Im5hbXFfMTBfZ2RwIikgJT4lIGZpbHRlcihnZW89PSJIUiIgJiBuYV9pdGVtPT0iUDciICYgc19hZGo9PSJOU0EiICYgdW5pdD09IkNMVjEwX01OQUMiKSAlPiUgc2VsZWN0KHRpbWUsaW09dmFsdWVzKSAlPiUgYXJyYW5nZSh0aW1lKQ0KDQojIG9wY2lqYSAxIC0gdXZpamVrIGdsZWRhbW8gZ29kacWhbmplIEJEUC1vdmUNCnBvbSA8LSBsZWZ0X2pvaW4ocG9tMSxwb20yLGJ5PSJ0aW1lIikgJT4lIGxlZnRfam9pbihwb20zLGJ5PSJ0aW1lIikgJT4lIGxlZnRfam9pbihwb200LGJ5PSJ0aW1lIikgJT4lIGxlZnRfam9pbihwb201LGJ5PSJ0aW1lIikgJT4lIGxlZnRfam9pbihwb202LGJ5PSJ0aW1lIikgJT4lIG11dGF0ZShkYXR1bSA9IG1ha2VfZGF0ZShpZmVsc2UobW9udGgodGltZSk+PTEwLHllYXIodGltZSkrMSx5ZWFyKHRpbWUpKSxpZmVsc2UobW9udGgodGltZSk+PTEwLDEsbW9udGgodGltZSkrMyksMSkgLSAxLCBiZHBfeSA9IChiZHAgKyBsYWcoYmRwLDEpKyBsYWcoYmRwLDIpICsgbGFnKGJkcCwzKSkqMTAwMDAwMCAsIGNfaGhfeSA9IChjX2hoICsgbGFnKGNfaGgsMSkrIGxhZyhjX2hoLDIpICsgbGFnKGNfaGgsMykpKjEwMDAwMDAgLCBjX2dvdnRfeSA9IChjX2dvdnQgKyBsYWcoY19nb3Z0LDEpKyBsYWcoY19nb3Z0LDIpICsgbGFnKGNfZ292dCwzKSkqMTAwMDAwMCAsIGlfZ3Jvc3NfeSA9IChpX2dyb3NzICsgbGFnKGlfZ3Jvc3MsMSkrIGxhZyhpX2dyb3NzLDIpICsgbGFnKGlfZ3Jvc3MsMykpKjEwMDAwMDAgLCBleF95ID0gKGV4ICsgbGFnKGV4LDEpKyBsYWcoZXgsMikgKyBsYWcoZXgsMykpKjEwMDAwMDAgLCBpbV95ID0gKGltICsgbGFnKGltLDEpKyBsYWcoaW0sMikgKyBsYWcoaW0sMykpKjEwMDAwMDApICU+JSBtdXRhdGUoZGJkcCA9IChiZHBfeS9sYWcoYmRwX3ksNCktMSkqMTAwICwgZG9wX2NfaGggPSAoY19oaF95L2xhZyhjX2hoX3ksNCktMSkqMTAwKmxhZyhjX2hoX3ksNCkvbGFnKGJkcF95LDQpICwgZG9wX2NfZ292dCA9IChjX2dvdnRfeS9sYWcoY19nb3Z0X3ksNCktMSkqMTAwKmxhZyhjX2dvdnRfeSw0KS9sYWcoYmRwX3ksNCkgLCBkb3BfaV9ncm9zcyA9IChpX2dyb3NzX3kvbGFnKGlfZ3Jvc3NfeSw0KS0xKSoxMDAqbGFnKGlfZ3Jvc3NfeSw0KS9sYWcoYmRwX3ksNCkgLCBkb3BfZXggPSAoZXhfeS9sYWcoZXhfeSw0KS0xKSoxMDAqbGFnKGV4X3ksNCkvbGFnKGJkcF95LDQpICwgZG9wX2ltID0gLShpbV95L2xhZyhpbV95LDQpLTEpKjEwMCpsYWcoaW1feSw0KS9sYWcoYmRwX3ksNCkpICU+JSBzZWxlY3QoZGF0dW0sZGJkcCxkb3BfY19oaCxkb3BfY19nb3Z0LGRvcF9pX2dyb3NzLGRvcF9leCxkb3BfaW0pICU+JSBuYS5vbWl0KCkNCmNvbG5hbWVzKHBvbSkgPC0gYygiZGF0dW0iLCJCRFAiLCJQb3Ryb8WhbmphIGt1xIdhbnN0YXZhIiwiSmF2bmEgcG90cm/FoW5qYSIsIkJydXRvIGludmVzdGljaWplIiwiSXp2b3oiLCJVdm96IikNCnBvbSA8LSBwb20gJT4lIGdhdGhlcihrZXkgPSAidmFyaWphYmxhIix2YWx1ZSA9ICJpem5vcyIsLWRhdHVtKQ0KZ2dwbG90KHBvbSAlPiUgZmlsdGVyKHZhcmlqYWJsYSE9IkJEUCIpLGFlcyh4PWRhdHVtLHk9aXpub3MsZmlsbD12YXJpamFibGEpKSArIGdlb21fY29sKHBvc2l0aW9uPSJzdGFjayIpICsgZ2VvbV9wb2ludChkYXRhPXBvbSAlPiUgZmlsdGVyKHZhcmlqYWJsYT09IkJEUCIpLGFlcyh4PWRhdHVtLHk9aXpub3MpKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLCBsZWdlbmQudGl0bGUgPSBlbGVtZW50X2JsYW5rKCkpICsgbGFicyh4PSIiLHk9IiIpDQpybShwb20xLHBvbTIscG9tMyxwb200LHBvbTUscG9tNixwb20pDQpgYGANCg0KIyMjIDUuMy4gU3ZqZXRza2EgQmFua2ENCg0KS29kIG5qaWggcHJpc3R1cCBwb2RhY2ltYSBmdW5rY2lvbmlyYSBuYSBzbGnEjWFuIG5hxI1pbiBrYW8gaSBrb2QgRUNCLWEsIGdkamUgc3Zha2kgaW5kaWthdG9yIGltYSBqZWRpbnN0dmVuaSBrb2QgLSBbcHJpbWplciB6YSBpbmRpa2F0b3IgdHJnb3ZpbmUgbmEgdHLFvmnFoXR1IGthcGl0YWxhIHUgJUJEUC1hXShodHRwczovL2RhdGEud29ybGRiYW5rLm9yZy9pbmRpY2F0b3IvQ00uTUtULlRSQUQuR0QuWlMpLg0KDQpgYGB7cn0NCmxpYnJhcnkod2JzdGF0cykNCnJlZyA9IGRhdGEuZnJhbWUoY3RyeT1jKCJBVCIsIkJFIiwiQkciLCJIUiIsIkNZIiwiQ1oiLCJESyIsIkVFIiwiRkkiLCJGUiIsIkRFIiwiR1IiLCJIVSIsIklFIiwiSVQiLCJMViIsIkxUIiwiTFUiLCJNVCIsIk5MIiwiUEwiLCJQVCIsIlJPIiwiU0siLCJTSSIsIkVTIiwiU0UiLCJHQiIsIlUyIiwiSTgiKSxjb3VudHJ5PWMoIkF1c3RyaWEiLCJCZWxnaXVtIiwiQnVsZ2FyaWEiLCJDcm9hdGlhIiwiQ3lwcnVzIiwiQ3plY2ggUmVwdWJsaWMiLCJEZW5tYXJrIiwiRXN0b25pYSIsIkZpbmxhbmQiLCJGcmFuY2UiLCJHZXJtYW55IiwiR3JlZWNlIiwiSHVuZ2FyeSIsIklyZWxhbmQiLCJJdGFseSIsIkxhdHZpYSIsIkxpdGh1YW5pYSIsIkx1eGVtYm91cmciLCJNYWx0YSIsIk5ldGhlcmxhbmRzIiwiUG9sYW5kIiwiUG9ydHVnYWwiLCJSb21hbmlhIiwiU2xvdmFrIFJlcHVibGljIiwiU2xvdmVuaWEiLCJTcGFpbiIsIlN3ZWRlbiIsIkdyZWF0IEJyaXRhaW4iLCJFQSBjaGFuZ2luZyBjb21wLiIsIkV1cm8gQXJlYSAxOSIpLHJlZ2lqYT1jKCJPdGhlciBFVSIsIk90aGVyIEVVIiwiQ0VFIiwiSFIiLCJPdGhlciBFVSIsIkNFRSIsIk90aGVyIEVVIiwiQ0VFIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJDRUUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiQ0VFIiwiQ0VFIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiQ0VFIiwiT3RoZXIgRVUiLCJDRUUiLCJDRUUiLCJDRUUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJFQSBjaGFuZ2luZyBjb21wLiIsIkV1cm8gQXJlYSAxOSIpKQ0Kc3RvY2tzX3RyYWRlZCA8LSB3YihpbmRpY2F0b3IgPSAiQ00uTUtULlRSQUQuR0QuWlMiKQ0KcG9tIDwtIHN0b2Nrc190cmFkZWQgJT4lIGZpbHRlcihpc28yYyAlaW4lIHJlZyRjdHJ5ICYgZGF0ZSAlaW4lIGMoIjIwMTQiLCIyMDE1IiwiMjAxNiIsIjIwMTciLCIyMDE4IikpICU+JSBzZWxlY3QoZGF0ZSxjdHJ5PWlzbzJjLHZhbHVlKSAlPiUgZ3JvdXBfYnkoY3RyeSkgJT4lIHN1bW1hcmlzZSh2YWx1ZT1tZWFuKHZhbHVlLG5hLnJtPVQpKSAlPiUgbGVmdF9qb2luKHJlZyxieT0iY3RyeSIpICU+JSBmaWx0ZXIoY3RyeSE9IlVTIikgJT4lIG11dGF0ZShyZWdpamE9aWZlbHNlKHJlZ2lqYT09IkNFRSIsIlplbWxqZSBTSUUiLGlmZWxzZShyZWdpamE9PSJPdGhlciBFVSIsIk9zdGFsZSBFVSB6ZW1samUiLCJIUiIpKSkNCmdncGxvdChwb20sYWVzKHg9cmVvcmRlcihjdHJ5LC12YWx1ZSkseT12YWx1ZSkpICsgZ2VvbV9jb2woYWVzKGZpbGw9cmVnaWphKSkgKyBsYWJzKHg9IiIseT0iIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIsbGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0Kcm0ocmVnLHN0b2Nrc190cmFkZWQscG9tKQ0KYGBgDQoNCiMjIyA1LjQuIE9FQ0QNCg0KSmVkYW4gZm9yYSBwcmltamVyIG1vZ3XEh25vc3RpIFItYSwgc3UgcmV6dWx0YXRpIGZpbmFuY2lqc2tlIHBpc21lbm9zdGkga29qdSBwcm92b2RpIE9FQ0QgaSBrb2p1IG9iamFsdmp1amUgW3UgUERGLXVdKGh0dHA6Ly93d3cub2VjZC5vcmcvZGFmL2Zpbi9maW5hbmNpYWwtZWR1Y2F0aW9uL09FQ0QtSU5GRS1JbnRlcm5hdGlvbmFsLVN1cnZleS1vZi1BZHVsdC1GaW5hbmNpYWwtTGl0ZXJhY3ktQ29tcGV0ZW5jaWVzLnBkZikuIFBvc3RvamkgcGFrZXQgdSBSLXUga29qaSBpbWEgc3Bvb2Jub3N0IMSNaXRhbmphIFBERi1vdmEgaSB1c3BpbyBqZSB1xI1pdGF0aSBvdmUgcG9kYXRrZSBzYSBzbGlrZSBuYSBzdHJhbmljaSAxMC4NCg0KYGBge3J9DQpsaWJyYXJ5KHRhYnVsaXplcikNCnBpc21lbm9zdF90YWJsaWNhIDwtIGV4dHJhY3RfdGFibGVzKCJodHRwOi8vd3d3Lm9lY2Qub3JnL2RhZi9maW4vZmluYW5jaWFsLWVkdWNhdGlvbi9PRUNELUlORkUtSW50ZXJuYXRpb25hbC1TdXJ2ZXktb2YtQWR1bHQtRmluYW5jaWFsLUxpdGVyYWN5LUNvbXBldGVuY2llcy5wZGYiKQ0KdGVtcCA8LSBwaXNtZW5vc3RfdGFibGljYVtbM11dDQp0ZW1wIDwtIGFzLmRhdGEuZnJhbWUodGVtcCkNCmNvbG5hbWVzKHRlbXApPC1jKCJjdHJ5X3Njb3JlIiwia25vd2xlZGdlX3Njb3JlIiwiYmVoYXZpb3VyX3Njb3JlIiwiYXR0aXR1ZGVfc2NvcmUiKQ0KdGVtcCA8LSB0ZW1wICU+JSBzZXBhcmF0ZShjdHJ5X3Njb3JlLGMoImNvdW50cnkiLCJmaW5hbmNpYWxfa25vd2xlZGdlIiksIiBcXCgiKSAlPiUgbXV0YXRlKGZpbmFuY2lhbF9rbm93bGVkZ2U9c3RyX3JlcGxhY2UoZmluYW5jaWFsX2tub3dsZWRnZSwiXFwpIiwiIikpICU+JSBtdXRhdGUoZmluYW5jaWFsX2tub3dsZWRnZT1hcy5udW1lcmljKGZpbmFuY2lhbF9rbm93bGVkZ2UpLGtub3dsZWRnZV9zY29yZT1hcy5jaGFyYWN0ZXIoa25vd2xlZGdlX3Njb3JlKSxiZWhhdmlvdXJfc2NvcmU9YXMuY2hhcmFjdGVyKGJlaGF2aW91cl9zY29yZSksYXR0aXR1ZGVfc2NvcmU9YXMuY2hhcmFjdGVyKGF0dGl0dWRlX3Njb3JlKSkgJT4lIG11dGF0ZShrbm93bGVkZ2Vfc2NvcmU9YXMubnVtZXJpYyhrbm93bGVkZ2Vfc2NvcmUpLGJlaGF2aW91cl9zY29yZT1hcy5udW1lcmljKGJlaGF2aW91cl9zY29yZSksYXR0aXR1ZGVfc2NvcmU9YXMubnVtZXJpYyhhdHRpdHVkZV9zY29yZSkpDQpmaW5hbmNpanNrYV9waXNtZW5vc3QgPC0gdGVtcA0KcmVnID0gZGF0YS5mcmFtZShjdHJ5PWMoIkFUIiwiQkUiLCJCRyIsIkhSIiwiQ1kiLCJDWiIsIkRLIiwiRUUiLCJGSSIsIkZSIiwiREUiLCJHUiIsIkhVIiwiSUUiLCJJVCIsIkxWIiwiTFQiLCJMVSIsIk1UIiwiTkwiLCJQTCIsIlBUIiwiUk8iLCJTSyIsIlNJIiwiRVMiLCJTRSIsIkdCIiwiVTIiLCJVUyIpLGNvdW50cnk9YygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLCJDemVjaCBSZXB1YmxpYyIsIkRlbm1hcmsiLCJFc3RvbmlhIiwiRmlubGFuZCIsIkZyYW5jZSIsIkdlcm1hbnkiLCJHcmVlY2UiLCJIdW5nYXJ5IiwiSXJlbGFuZCIsIkl0YWx5IiwiTGF0dmlhIiwiTGl0aHVhbmlhIiwiTHV4ZW1ib3VyZyIsIk1hbHRhIiwiTmV0aGVybGFuZHMiLCJQb2xhbmQiLCJQb3J0dWdhbCIsIlJvbWFuaWEiLCJTbG92YWsgUmVwdWJsaWMiLCJTbG92ZW5pYSIsIlNwYWluIiwiU3dlZGVuIiwiVW5pdGVkIEtpbmdkb20iLCJFQSBjaGFuZ2luZyBjb21wLiIsIlVuaXRlZCBTdGF0ZXMiKSxyZWdpamE9YygiT3RoZXIgRVUiLCJPdGhlciBFVSIsIkNFRSIsIkhSIiwiT3RoZXIgRVUiLCJDRUUiLCJPdGhlciBFVSIsIkNFRSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiQ0VFIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIkNFRSIsIkNFRSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIkNFRSIsIk90aGVyIEVVIiwiQ0VFIiwiQ0VFIiwiQ0VFIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiRUEgY2hhbmdpbmcgY29tcC4iLCJVUyIpKQ0KcG9tIDwtIGZpbmFuY2lqc2thX3Bpc21lbm9zdCAlPiUgZmlsdGVyKGNvdW50cnkgJWluJSByZWckY291bnRyeSkgJT4lIGxlZnRfam9pbihyZWcsYnk9ImNvdW50cnkiKQ0KZ2dwbG90KHBvbSxhZXMoeD1yZW9yZGVyKGN0cnksLWZpbmFuY2lhbF9rbm93bGVkZ2UpLHk9ZmluYW5jaWFsX2tub3dsZWRnZSkpICsgZ2VvbV9jb2woYWVzKGZpbGw9cmVnaWphKSkgKyBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBmaW5hbmNpanNrYV9waXNtZW5vc3QkZmluYW5jaWFsX2tub3dsZWRnZVtmaW5hbmNpanNrYV9waXNtZW5vc3QkY291bnRyeT09IkF2ZXJhZ2UsIGFsbCBjb3VudHJpZXMiXSkgKyBsYWJzKHg9IiIseT0iRmluYW5jaWpza2EgcGlzbWVub3N0IikgKyB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIpDQpybShwaXNtZW5vc3RfdGFibGljYSx0ZW1wLGZpbmFuY2lqc2thX3Bpc21lbm9zdCxwb20pDQpgYGANCg0KIyMjIDUuNS4gRUlPUEEgcG9kYWNpDQoNCkVJT1BBIG5pamUgbmFwcmVkbmEga2FvIEVDQiBpbGkgRVVST1NUQVQgdSBvYmphdmkgcG9kYXRha2EgaSBvYmphdmxqdWplIGloIFt1IGV4Y2VsaW1hXShodHRwczovL3d3dy5laW9wYS5ldXJvcGEuZXUvdG9vbHMtYW5kLWRhdGEvaW5zdXJhbmNlLXN0YXRpc3RpY3NfZW4pLCBubyBpIHphIHRvIGltYW1vIHNpc3RlbS4NCg0KPiBza3JpcHRhICoqRUlPUEFfZG9odmF0X3BvZGF0YWthLlIqKg0KDQojIyA2LiBQcmlwcmVtYSBwb2RhdGFrYQ0KDQpWYcW+bm8gamUgbmFnbGFzaXRpIGRhIGplIHphIGt2YWxpdGV0bnUgYW5hbGl6dSBudcW+bmEgZG9icmEgcHJpcHJlbWEgcG9kYXRha2EuIFByZW1hIFtpc3RyYcW+aXZhbmp1IENyb3dkRmxvd2VyLWFdKGh0dHBzOi8vd3d3LmZvcmJlcy5jb20vc2l0ZXMvZ2lscHJlc3MvMjAxNi8wMy8yMy9kYXRhLXByZXBhcmF0aW9uLW1vc3QtdGltZS1jb25zdW1pbmctbGVhc3QtZW5qb3lhYmxlLWRhdGEtc2NpZW5jZS10YXNrLXN1cnZleS1zYXlzLyM1Y2YzNzk1NmY2MzcpLCB1ICpEYXRhIHNjaWVuY2UtdSogc2UgKio4MCUgdnJlbWVuYSBzdm9kaSBuYSBwcmlwcmVtdSBwb2RhdGFrYSoqLCDFoXRvIGplIHVqZWRubyBpIG5ham1hbmplIHphbmltbGppdiBkaW8gcHJvY2VzYS4NCg0KIVtdKGNpc2NlbmplX3BvZGF0YWthX2Fua2V0YS5QTkcpDQoNCiMjIyA2LjEuIFRpZHkgc3RydWt0dXJhIHBvZGF0YWthDQoNCktha28gYmkgc2UgdnJpamVtZSBwb3RyZWJubyB6YSBvYnJhZHUgcG9kYXRha2EsIGFsaSBpIHZyaWplbWUgemEgYW5hbGl6dSBwb2RhdGFrYSBzbWFuamlsbywgbnXFvm5vIGplIGRhIHBvZGFjaSBidWR1IHUgdGlkeSBmb3JtYXR1Lg0KDQohW10oVGlkeV9kYXRhLlBORykNCg0KIyMjIDYuMi4gRmluYW5jaWpza2kgcmHEjXVuaQ0KDQpGaW5hbmNpanNrZSByYcSNdW5lIGRvYml2YW1vIG5hIGtyYWpuamUgbmVzdHJ1a3R1cmlyYW4gbmHEjWluIGkga29qaSBzZSBuYWxhemUgW292ZGplXShEOlxtYmFtYmFcREFUQVxGaW5hbmNpanNraV9yYWN1bmkpLiBPbm8gxaF0byBSIG9tb2d1xId1amUgamUgc2tsYXBhbmplIHUgMSBiYXp1IGtvamEgc2Ugb25kYSBtb8W+ZSBrb3Jpc3RpdGkgemEgYW5hbGl6dSBpIG5lIHNhbW8gdG8gbmVnbyBqZSBuYSB0YWogbmHEjWluIDk3ME1CIHBvZGF0YWthIHUgZXhjZWxpbWEgcHJldHZvcmVubyB1IDIuN01CIHZlbGlraSBkYXRhZnJhbWUuDQoNCj4gZm9sZGVyICoqRmluYW5jaWpza2lfcmFjdW5pKioNCg0KT3Zha3ZhIHN0cnVrdHVyYSBwb2RhdGFrYSBvbW9ndcSHdWplIHNsamVkZcSHZSBzbGlrZToNCg0KYGBge3J9DQpsaWJyYXJ5KGlncmFwaCkNCiMgU2xpa2EgMTEuIE1yZcW+YSB0cmFuc2FrY2lqYSAjIyMjDQpsb2FkKCJGaW5SYWN1bmkuUmRhIikNCnQwIDwtIGFzLkRhdGUoIjIwMTItMDMtMzEiKQ0KdDEgPC0gYXMuRGF0ZSgiMjAxOS0wNi0zMCIpDQpicl9kYW5hIDwtIGFzLm51bWVyaWModDEtdDApDQojIGFudWFsaXppcmFuaSByYXN0IHNla3RvcmEgbmEgdGVtZWxqdSB0cmFuc2FrY2lqYSBpem1lxJF1IHQwIGkgdDENCiMgcG/EjWV0bmEgc3RhbmphDQpwb20xMSA8LSBmaW5hbmNpanNraV9yYWN1bmkgJT4lIG11dGF0ZShzZWt0b3JfbWIgPSBpZmVsc2Uoc2VrdG9yX21iPT0iT3N0YWxpIGZpbmFuY2lqc2tpIHBvc3JlZG5pY2kiLCJPc3RhbGUgRkkiLHNla3Rvcl9tYikpICU+JSBncm91cF9ieShkYXR1bSxzZWt0b3JfbWIpICU+JSBmaWx0ZXIodnJzdGFfaXpub3NhPT0iQkFMIFQiICYgdnJzdGFfaW1vdmluZT09IlRvdGFsIiAmIHJhemluYT09IkFzc2V0cyIgJiAhc2VrdG9yICVpbiUgYygiVE9UQUwiLCJOQSIpICYgIXByb3R1c3RyYW5hICVpbiUgYygiVE9UQUwiLCJOQSIpICYgZGF0dW09PXQwKSAlPiUgc3VtbWFyaXNlKHN0YW5qYT1zdW0oaXpub3MsbmEucm0gPSBUKSkNCiMgdWt1cG5lIHRyYW5zYWtjaWplIHBvIHNla3RvcmltYSAoemEgaXpyYcSNdW4gcmFzdGEgbmEgdGVtZWxqdSB0cmFuc2FrY2lqYSkNCnBvbTEyIDwtIGZpbmFuY2lqc2tpX3JhY3VuaSAlPiUgbXV0YXRlKHNla3Rvcl9tYiA9IGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9zdGFsZSBGSSIsc2VrdG9yX21iKSkgJT4lIGdyb3VwX2J5KHNla3Rvcl9tYikgJT4lIGZpbHRlcih2cnN0YV9pem5vc2E9PSJUUkFOUyBUIiAmIHZyc3RhX2ltb3ZpbmU9PSJUb3RhbCIgJiByYXppbmE9PSJBc3NldHMiICYgIXNla3RvciAlaW4lIGMoIlRPVEFMIiwiTkEiKSAmICFwcm90dXN0cmFuYSAlaW4lIGMoIlRPVEFMIiwiTkEiKSAmIGRhdHVtPnQwKSAlPiUgc3VtbWFyaXNlKGN1bV90cmFucz1zdW0oaXpub3MsbmEucm0gPSBUKSkNCiMgaXpyYcSNdW4gcmFzdGEgbmEgdGVtZWxqdSB0cmFuc2FrY2lqYQ0KcG9tMSA8LSBsZWZ0X2pvaW4ocG9tMTEscG9tMTIsYnk9InNla3Rvcl9tYiIpICU+JSBtdXRhdGUoY3VtX3Jhc3Q9KChjdW1fdHJhbnMpL3N0YW5qYSkqMTAwKSAlPiUgbXV0YXRlKGFuX3Jhc3Q9KCgxK2N1bV9yYXN0LzEwMCleKDM2NS9icl9kYW5hKS0xKSoxMDApDQojIGRvcHJpbm9zaSBwcm90dXN0cmFua2kgYW51YWxpemlyYW5vbSByYXN0dSBzZWt0b3JhIG5hIHRlbWVsanUgdHJhbnNha2NpamEgaXptZcSRdSB0MCBpIHQxDQojIGt1bXVsYXRpdm5lIHRyYW5zYWtjaWplIHBvIHByb3R1c3RyYW5jaQ0KcG9tMiA8LSBmaW5hbmNpanNraV9yYWN1bmkgJT4lIG11dGF0ZShzZWt0b3JfbWIgPSBpZmVsc2Uoc2VrdG9yX21iPT0iT3N0YWxpIGZpbmFuY2lqc2tpIHBvc3JlZG5pY2kiLCJPc3RhbGUgRkkiLHNla3Rvcl9tYikgLCBwcm90dXN0cmFuYV9tYiA9IGlmZWxzZShwcm90dXN0cmFuYV9tYj09Ik9zdGFsaSBmaW5hbmNpanNraSBwb3NyZWRuaWNpIiwiT3N0YWxlIEZJIixwcm90dXN0cmFuYV9tYikpICU+JSBncm91cF9ieShzZWt0b3JfbWIscHJvdHVzdHJhbmFfbWIpICU+JSBmaWx0ZXIodnJzdGFfaXpub3NhPT0iVFJBTlMgVCIgJiB2cnN0YV9pbW92aW5lPT0iVG90YWwiICYgcmF6aW5hPT0iQXNzZXRzIiAmICFzZWt0b3IgJWluJSBjKCJUT1RBTCIsIk5BIikgJiAhcHJvdHVzdHJhbmEgJWluJSBjKCJUT1RBTCIsIk5BIikgJiBkYXR1bT50MCkgJT4lIHN1bW1hcmlzZShjdW1fdHJhbnNfc2VrdD1zdW0oaXpub3MsbmEucm0gPSBUKSkNCiMgc2tsYXBhbmplIGkgcmHEjXVuYW5qZSBzdG9wYSByYXN0YQ0KcG9tIDwtIGxlZnRfam9pbihwb20yLHBvbTEsYnk9Yygic2VrdG9yX21iIikpICU+JSBtdXRhdGUoY3VtX2RvcF9zZWt0ID0gKGN1bV90cmFuc19zZWt0L3N0YW5qYSkqMTAwKSAlPiUgbXV0YXRlKGRvcHJpbm9zX3RyYW5zPSgoMStjdW1fZG9wX3Nla3QvMTAwKV4oMzY1L2JyX2RhbmEpLTEpKjEwMCkNCg0KIyBkZWZpbmlyYW5qZSBicmlkb3ZhDQpicmlkb3ZpIDwtIHBvbSAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSBtdXRhdGUoc2VrdG9yX21iPWlmZWxzZShzZWt0b3JfbWI9PSJQb2R1emXEh2EiLCJQT0QiLGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGUgRkkiLCJPRkkiLGlmZWxzZShzZWt0b3JfbWI9PSJDZW50cmFsbmEgYmFua2EiLCJDQiIsaWZlbHNlKHNla3Rvcl9tYj09IktyZWRpdG5lIGluc3RpdHVjaWplIiwiS0kiLGlmZWxzZShzZWt0b3JfbWI9PSJJbnZlc3RpY2lqc2tpIGZvbmRvdmkiLCJJRiIsaWZlbHNlKHNla3Rvcl9tYj09Ik9zaWd1cmFuamEiLCJPUyIsaWZlbHNlKHNla3Rvcl9tYj09Ik1pcm92aW5za2kgZm9uZG92aSIsIk1GIixpZmVsc2Uoc2VrdG9yX21iPT0iRHLFvmF2YSIsIkRSxb0iLGlmZWxzZShzZWt0b3JfbWI9PSJTdGFub3ZuacWhdHZvIiwiS1XEhiIsaWZlbHNlKHNla3Rvcl9tYj09Iklub3plbXN0dm8iLCJJTk8iLGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9GUCIsIk5BIikpKSkpKSkpKSkpKSAlPiUgbXV0YXRlKHByb3R1c3RyYW5hX21iPWlmZWxzZShwcm90dXN0cmFuYV9tYj09IlBvZHV6ZcSHYSIsIlBPRCIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iT3N0YWxlIEZJIiwiT0ZJIixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJDZW50cmFsbmEgYmFua2EiLCJDQiIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iS3JlZGl0bmUgaW5zdGl0dWNpamUiLCJLSSIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iSW52ZXN0aWNpanNraSBmb25kb3ZpIiwiSUYiLGlmZWxzZShwcm90dXN0cmFuYV9tYj09Ik9zaWd1cmFuamEiLCJPUyIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iTWlyb3ZpbnNraSBmb25kb3ZpIiwiTUYiLGlmZWxzZShwcm90dXN0cmFuYV9tYj09IkRyxb5hdmEiLCJEUsW9IixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJTdGFub3ZuacWhdHZvIiwiS1XEhiIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iSW5vemVtc3R2byIsIklOTyIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iT3N0YWxpIGZpbmFuY2lqc2tpIHBvc3JlZG5pY2kiLCJPRlAiLCJOQSIpKSkpKSkpKSkpKSkNCg0KIyBkZWZpbmlyYW5qZSB2cmhvdmEgDQp2cmhvdmkgPC0gcG9tMSAlPiUgdW5ncm91cCgpICU+JSBtdXRhdGUoc2VrdG9yX21iPWlmZWxzZShzZWt0b3JfbWI9PSJQb2R1emXEh2EiLCJQT0QiLGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGUgRkkiLCJPRkkiLGlmZWxzZShzZWt0b3JfbWI9PSJDZW50cmFsbmEgYmFua2EiLCJDQiIsaWZlbHNlKHNla3Rvcl9tYj09IktyZWRpdG5lIGluc3RpdHVjaWplIiwiS0kiLGlmZWxzZShzZWt0b3JfbWI9PSJJbnZlc3RpY2lqc2tpIGZvbmRvdmkiLCJJRiIsaWZlbHNlKHNla3Rvcl9tYj09Ik9zaWd1cmFuamEiLCJPUyIsaWZlbHNlKHNla3Rvcl9tYj09Ik1pcm92aW5za2kgZm9uZG92aSIsIk1GIixpZmVsc2Uoc2VrdG9yX21iPT0iRHLFvmF2YSIsIkRSxb0iLGlmZWxzZShzZWt0b3JfbWI9PSJTdGFub3ZuacWhdHZvIiwiS1XEhiIsaWZlbHNlKHNla3Rvcl9tYj09Iklub3plbXN0dm8iLCJJTk8iLGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9GUCIsIk5BIikpKSkpKSkpKSkpKSAlPiUgbXV0YXRlKGhhbmZhPWlmZWxzZShzZWt0b3JfbWIgJWluJSBjKCJJRiIsIk1GIiwiT1MiLCJPRkkiLCJPRlAiKSwiZGEiLCJuZSIpKSAlPiUgZmlsdGVyKHNla3Rvcl9tYiE9IkNCIikgJT4lIHNlbGVjdChzZWt0b3JfbWIscmFzdF90cmFucz1hbl9yYXN0LGhhbmZhKQ0KDQojIHV6aW1hbmplIHNhbW8gYnJpZG92YSBrb2ppIHN1IHJhemxpxI1pdG8gb2QgMCUgaSBzYW1vIG9uaWggYnJpZG92YSBrb2ppIGltYWp1IHZlemUgc2EgSEFORkEtaW5pbSBzZWt0b3JpbWENCmJyaWRvdmkgPC0gYnJpZG92aSAlPiUgZmlsdGVyKChkb3ByaW5vc190cmFuczw9LTAuNSB8IGRvcHJpbm9zX3RyYW5zPj0wLjUpICYgKHNla3Rvcl9tYiAlaW4lIGMoIk1GIiwiT1MiLCJJRiIsIk9GSSIsIk9GUCIpIHwgcHJvdHVzdHJhbmFfbWIgJWluJSBjKCJNRiIsIk9TIiwiSUYiLCJPRkkiLCJPRlAiKSkpICU+JSBmaWx0ZXIoc2VrdG9yX21iIT1wcm90dXN0cmFuYV9tYikNCg0KIyBrcmVpcmFuamUgbXJlxb5ub2cgb2JqZWt0YQ0KZ3JhZiA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoZCA9IGJyaWRvdmksIHZlcnRpY2VzID0gdnJob3ZpLCBkaXJlY3RlZCA9IFQpDQojIHBvc3RhdmxqYW5qZSBib2plIHZyaGEgKGFrbyByYXN0YW8gemVsZW5vLCBha28gcGFvIG9uZGEgY3J2ZW5vKQ0KVihncmFmKSRjb2xvciA8LSBpZmVsc2UoVihncmFmKSRyYXN0X3RyYW5zIDw9KC0xMCksICJmaXJlYnJpY2s0IiwgaWZlbHNlKFYoZ3JhZikkcmFzdF90cmFucyA8PSgtNSksIm9yYW5nZXJlZCIsaWZlbHNlKFYoZ3JhZikkcmFzdF90cmFuczw9MCwibGlnaHRzYWxtb24iLGlmZWxzZShWKGdyYWYpJHJhc3RfdHJhbnMgPD01LCJnb2xkIixpZmVsc2UoVihncmFmKSRyYXN0X3RyYW5zIDw9MTAsInllbGxvd2dyZWVuIiwic2VhZ3JlZW40IikpKSkpDQojIHBvc3RhdmxqYW5qZSBib2plIGJyaWRhIChha28gcmFzbGEgemVsZW5vLCBha28gcGFsYSBjcnZlbm8pDQpFKGdyYWYpJGNvbG9yIDwtIGlmZWxzZShFKGdyYWYpJGRvcHJpbm9zX3RyYW5zIDw9KC01KSwgImZpcmVicmljazQiLCBpZmVsc2UoRShncmFmKSRkb3ByaW5vc190cmFucyA8PSgtMi41KSwib3JhbmdlcmVkIixpZmVsc2UoRShncmFmKSRkb3ByaW5vc190cmFucyA8PTAsImxpZ2h0c2FsbW9uIixpZmVsc2UoRShncmFmKSRkb3ByaW5vc190cmFucyA8PTIuNSwiZ29sZCIsaWZlbHNlKEUoZ3JhZikkZG9wcmlub3NfdHJhbnMgPD01LCJ5ZWxsb3dncmVlbiIsInNlYWdyZWVuNCIpKSkpKQ0KIyBzbGlrYSBtcmXFvmUgcG92ZXphbm9zdGkgLSBqZWRuYWtlIHZlbGnEjWluZSB2cmhvdmENCnBsb3QoZ3JhZiwgdmVydGV4LnNpemUgPSAyNSwgZWRnZS5hcnJvdy5zaXplID0gMC41LCBsYXlvdXQ9bGF5b3V0X25pY2VseShncmFmKSwgdmVydGV4LmxhYmVsLmNvbG9yID0gImJsYWNrIiwgdmVydGV4LmZyYW1lLmNvbG9yPU5BLHZlcnRleC5zaGFwZT1pZmVsc2UoVihncmFmKSRoYW5mYT09ImRhIiwic3F1YXJlIiwiY2lyY2xlIikpDQojIEFkZCBhIGxlZ2VuZA0KbGVnZW5kKCJ0b3BsZWZ0IiwgbGVnZW5kPWMoIjwtb287LTEwXSA7IDwtMTA7LTVdIiwgIjwtMTA7LTVdIDsgPC01Oy0yLDVdIiwiPC01OzBdIDsgPC0yLDU7LTAsNV0iLCI8MDs1XSA7IFswLDU7Miw1XSIsIjw1OzEwXSA7IDwyLDU7NV0iLCI8MTA7K29vPiA7IDw1Oytvbz4iKSwgZmlsbD1jKCJmaXJlYnJpY2s0IiwgIm9yYW5nZXJlZCIsImxpZ2h0c2FsbW9uIiwiZ29sZCIsInllbGxvd2dyZWVuIiwic2VhZ3JlZW40IiksIHRpdGxlID0gIlZyaG92aSAocmFzdCBuYSB0ZW1lbGp1IHRyYW5zYWtjaWphKSA7IFxuIFN0cmVsaWNlIChkb3ByaW5vc2kgcmFzdHUpIiwgY2V4PTAuOCwgYnR5PSJuIikNCiMgYnJpc2FuamUgcHJpdnJlbWVuaWggdGFibGljYQ0Kcm0odDAsdDEsYnJfZGFuYSxwb20xLHBvbTIscG9tMTEscG9tMTIscG9tLGJyaWRvdmksdnJob3ZpLGdyYWYpDQoNCiMgU2xpa2EgMTIuIE1yZcW+YSBzdGFuamEgIyMjIw0KemFkbmppX2RhdHVtIDwtICIyMDE5LTA2LTMwIg0KIyB2ZWxpxI1pbmEgZGlyZWt0bmUgcG92ZXphbm9zdGkgdSBhcHNvbHV0bm9qIHZyaWplZG5vc3RpDQpwb20xIDwtIGZpbmFuY2lqc2tpX3JhY3VuaSAlPiUgbXV0YXRlKHNla3Rvcl9tYiA9IGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9zdGFsZSBGSSIsc2VrdG9yX21iKSAsIHByb3R1c3RyYW5hX21iID0gaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iT3N0YWxpIGZpbmFuY2lqc2tpIHBvc3JlZG5pY2kiLCJPc3RhbGUgRkkiLHByb3R1c3RyYW5hX21iKSkgJT4lIGZpbHRlcihkYXR1bT09emFkbmppX2RhdHVtICYgdnJzdGFfaXpub3NhPT0iQkFMIFQiICYgdnJzdGFfaW1vdmluZT09IlRvdGFsIiAmIHJhemluYT09IkFzc2V0cyIgJiAhc2VrdG9yICVpbiUgYygiVE9UQUwiLCJOQSIpICYgIXByb3R1c3RyYW5hICVpbiUgYygiVE9UQUwiLCJOQSIpKSAlPiUgZ3JvdXBfYnkoc2VrdG9yX21iLHByb3R1c3RyYW5hX21iKSAlPiUgc3VtbWFyaXNlKGl6bm9zPXN1bShpem5vcyxuYS5ybSA9IFQpLzEwMDAwMDAwMDApDQojIHVrdXBuYSB2ZWxpxI1pbmEgc2VrdG9yYSAob25hIMSHZSBuYW0gc2x1xb5pdGkgZGEgcmVsYXRpdml6aXJhbW8gcG92ZXphbm9zdCBpIG9ib2ppbW8gdSA0IGJvamUpDQpwb20yIDwtIGZpbmFuY2lqc2tpX3JhY3VuaSAlPiUgbXV0YXRlKHNla3Rvcl9tYiA9IGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9zdGFsZSBGSSIsc2VrdG9yX21iKSkgJT4lIGZpbHRlcihkYXR1bT09emFkbmppX2RhdHVtICYgdnJzdGFfaXpub3NhPT0iQkFMIFQiICYgdnJzdGFfaW1vdmluZT09IlRvdGFsIiAmIHJhemluYT09IkFzc2V0cyIgJiAhc2VrdG9yICVpbiUgYygiVE9UQUwiLCJOQSIpICYgcHJvdHVzdHJhbmEgJWluJSBjKCJUT1RBTCIpKSAlPiUgZ3JvdXBfYnkoc2VrdG9yX21iKSAlPiUgc3VtbWFyaXNlKHZlbGljaW5hX3Nla3Rvcj1zdW0oaXpub3MsbmEucm0gPSBUKS8xMDAwMDAwMDAwKQ0KIyB1a3VwbmEgdmVsacSNaW5hIHByb3R1c3RyYW5lIChvbmEgxIdlIG5hbSBzbHXFvml0aSBkYSByZWxhdGl2aXppcmFtbyBwb3ZlemFub3N0IGkga3JlaXJhbW8gZGVibGppbnUgbGluaWplKQ0KcG9tMyA8LSBmaW5hbmNpanNraV9yYWN1bmkgJT4lIG11dGF0ZShwcm90dXN0cmFuYV9tYiA9IGlmZWxzZShwcm90dXN0cmFuYV9tYj09Ik9zdGFsaSBmaW5hbmNpanNraSBwb3NyZWRuaWNpIiwiT3N0YWxlIEZJIixwcm90dXN0cmFuYV9tYikpICU+JSBmaWx0ZXIoZGF0dW09PXphZG5qaV9kYXR1bSAmIHZyc3RhX2l6bm9zYT09IkJBTCBUIiAmIHZyc3RhX2ltb3ZpbmU9PSJUb3RhbCIgJiByYXppbmE9PSJBc3NldHMiICYgIXByb3R1c3RyYW5hICVpbiUgYygiVE9UQUwiLCJOQSIpICYgc2VrdG9yICVpbiUgYygiVE9UQUwiKSkgJT4lIGdyb3VwX2J5KHByb3R1c3RyYW5hX21iKSAlPiUgc3VtbWFyaXNlKHZlbGljaW5hX3Byb3R1c3RyYW5hPXN1bShpem5vcyxuYS5ybSA9IFQpLzEwMDAwMDAwMDApDQojIHVrdXBuYSB2ZWxpxI1pbmEgaXpsb8W+ZW5vc3RpIHNla3RvcnUgZmluYW5jaWpza2loIHVzbHVnYSAob25hIMSHZSBuYW0gc2x1xb5pdGkgZGEgcmVsYXRpdml6aXJhbW8gcG92ZXphbm9zdCBpIGtyZWlyYW1vIHZlbGnEjWludSBrdWdsZSB6YSBuZUhBTkZBLWluZSB2cmhvdmUpDQpwb200IDwtIGZpbmFuY2lqc2tpX3JhY3VuaSAlPiUgbXV0YXRlKHNla3Rvcl9tYiA9IGlmZWxzZShzZWt0b3JfbWI9PSJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9zdGFsZSBGSSIsc2VrdG9yX21iKSkgJT4lIGZpbHRlcihkYXR1bT09emFkbmppX2RhdHVtICYgdnJzdGFfaXpub3NhPT0iQkFMIFQiICYgdnJzdGFfaW1vdmluZT09IlRvdGFsIiAmIHJhemluYT09IkxpYWJpbGl0aWVzIiAmICFzZWt0b3IgJWluJSBjKCJUT1RBTCIsIk5BIikgJiBwcm90dXN0cmFuYV9tYiAlaW4lIGMoIk1pcm92aW5za2kgZm9uZG92aSIsIk9zaWd1cmFuamEiLCJJbnZlc3RpY2lqc2tpIGZvbmRvdmkiLCJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9zdGFsZSBGSSIpKSAlPiUgZ3JvdXBfYnkoc2VrdG9yX21iKSAlPiUgc3VtbWFyaXNlKGl6bG96ZW5vc3RfaGFuZmE9c3VtKGl6bm9zLG5hLnJtID0gVCkvMTAwMDAwMDAwMCkNCiMgc2tsYXBhbmplIHUgMSB0aWJibGUNCmJyaWRvdmkgPC0gbGVmdF9qb2luKHBvbTEscG9tMixieT0ic2VrdG9yX21iIikgJT4lIGxlZnRfam9pbihwb20zLGJ5PSJwcm90dXN0cmFuYV9tYiIpICU+JSBsZWZ0X2pvaW4ocG9tNCxieT0ic2VrdG9yX21iIikgJT4lIG11dGF0ZShpemxvemVub3N0X3ZlbGljaW5hX3Nla3Rvcj1pem5vcy92ZWxpY2luYV9zZWt0b3IqMTAwICwgaXpsb3plbm9zdF92ZWxpY2luYV9wcm90dXN0cmFuYT1pem5vcy92ZWxpY2luYV9wcm90dXN0cmFuYSoxMDApICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIG11dGF0ZShzZWt0b3JfbWI9aWZlbHNlKHNla3Rvcl9tYj09IlBvZHV6ZcSHYSIsIlBPRCIsaWZlbHNlKHNla3Rvcl9tYj09Ik9zdGFsZSBGSSIsIk9GSSIsaWZlbHNlKHNla3Rvcl9tYj09IkNlbnRyYWxuYSBiYW5rYSIsIkNCIixpZmVsc2Uoc2VrdG9yX21iPT0iS3JlZGl0bmUgaW5zdGl0dWNpamUiLCJLSSIsaWZlbHNlKHNla3Rvcl9tYj09IkludmVzdGljaWpza2kgZm9uZG92aSIsIklGIixpZmVsc2Uoc2VrdG9yX21iPT0iT3NpZ3VyYW5qYSIsIk9TIixpZmVsc2Uoc2VrdG9yX21iPT0iTWlyb3ZpbnNraSBmb25kb3ZpIiwiTUYiLGlmZWxzZShzZWt0b3JfbWI9PSJEcsW+YXZhIiwiRFLFvSIsaWZlbHNlKHNla3Rvcl9tYj09IlN0YW5vdm5pxaF0dm8iLCJLVcSGIixpZmVsc2Uoc2VrdG9yX21iPT0iSW5vemVtc3R2byIsIklOTyIsaWZlbHNlKHNla3Rvcl9tYj09Ik9zdGFsaSBmaW5hbmNpanNraSBwb3NyZWRuaWNpIiwiT0ZQIiwiTkEiKSkpKSkpKSkpKSkpICU+JSBtdXRhdGUocHJvdHVzdHJhbmFfbWI9aWZlbHNlKHByb3R1c3RyYW5hX21iPT0iUG9kdXplxIdhIiwiUE9EIixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJPc3RhbGUgRkkiLCJPRkkiLGlmZWxzZShwcm90dXN0cmFuYV9tYj09IkNlbnRyYWxuYSBiYW5rYSIsIkNCIixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJLcmVkaXRuZSBpbnN0aXR1Y2lqZSIsIktJIixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJJbnZlc3RpY2lqc2tpIGZvbmRvdmkiLCJJRiIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iT3NpZ3VyYW5qYSIsIk9TIixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJNaXJvdmluc2tpIGZvbmRvdmkiLCJNRiIsaWZlbHNlKHByb3R1c3RyYW5hX21iPT0iRHLFvmF2YSIsIkRSxb0iLGlmZWxzZShwcm90dXN0cmFuYV9tYj09IlN0YW5vdm5pxaF0dm8iLCJLVcSGIixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJJbm96ZW1zdHZvIiwiSU5PIixpZmVsc2UocHJvdHVzdHJhbmFfbWI9PSJPc3RhbGkgZmluYW5jaWpza2kgcG9zcmVkbmljaSIsIk9GUCIsIk5BIikpKSkpKSkpKSkpKQ0KDQojIHV6aW1hbmplIHNhbW8gYnJpZG92YSBrb2ppIHN1IHZlxIdpIG9kIDUlIGkgc2FtbyBvbmloIGJyaWRvdmEga29qaSBpbWFqdSB2ZXplIHNhIEhBTkZBLWluaW0gc2VrdG9yaW1hDQpicmlkb3ZpIDwtIGJyaWRvdmkgJT4lIGZpbHRlcihpemxvemVub3N0X3ZlbGljaW5hX3Nla3Rvcj41ICYgKHNla3Rvcl9tYiAlaW4lIGMoIk1GIiwiT1MiLCJJRiIsIk9GSSIsIk9GUCIpIHwgcHJvdHVzdHJhbmFfbWIgJWluJSBjKCJNRiIsIk9TIiwiSUYiLCJPRkkiLCJPRlAiKSkpDQojIGRlZmluaXJhbmplIHZyaG92YSANCnZyaG92aSA8LSBsZWZ0X2pvaW4ocG9tMixwb200LGJ5PSJzZWt0b3JfbWIiKSAlPiUgbXV0YXRlKHNla3Rvcl9tYj1pZmVsc2Uoc2VrdG9yX21iPT0iUG9kdXplxIdhIiwiUE9EIixpZmVsc2Uoc2VrdG9yX21iPT0iT3N0YWxlIEZJIiwiT0ZJIixpZmVsc2Uoc2VrdG9yX21iPT0iQ2VudHJhbG5hIGJhbmthIiwiQ0IiLGlmZWxzZShzZWt0b3JfbWI9PSJLcmVkaXRuZSBpbnN0aXR1Y2lqZSIsIktJIixpZmVsc2Uoc2VrdG9yX21iPT0iSW52ZXN0aWNpanNraSBmb25kb3ZpIiwiSUYiLGlmZWxzZShzZWt0b3JfbWI9PSJPc2lndXJhbmphIiwiT1MiLGlmZWxzZShzZWt0b3JfbWI9PSJNaXJvdmluc2tpIGZvbmRvdmkiLCJNRiIsaWZlbHNlKHNla3Rvcl9tYj09IkRyxb5hdmEiLCJEUsW9IixpZmVsc2Uoc2VrdG9yX21iPT0iU3Rhbm92bmnFoXR2byIsIktVxIYiLGlmZWxzZShzZWt0b3JfbWI9PSJJbm96ZW1zdHZvIiwiSU5PIixpZmVsc2Uoc2VrdG9yX21iPT0iT3N0YWxpIGZpbmFuY2lqc2tpIHBvc3JlZG5pY2kiLCJPRlAiLCJOQSIpKSkpKSkpKSkpKSkgJT4lIG11dGF0ZShoYW5mYT1pZmVsc2Uoc2VrdG9yX21iICVpbiUgYygiSUYiLCJNRiIsIk9TIiwiT0ZJIiwiT0ZQIiksImRhIiwibmUiKSkgJT4lIG11dGF0ZSh2ZWxpY2luYV9rcnVnYT1pZmVsc2UoaGFuZmE9PSJkYSIsdmVsaWNpbmFfc2VrdG9yLGl6bG96ZW5vc3RfaGFuZmEpKSAlPiUgZmlsdGVyKHNla3Rvcl9tYiE9IkNCIikNCg0KIyBrcmVpcmFuamUgbXJlxb5ub2cgb2JqZWt0YQ0KZ3JhZiA8LSBncmFwaF9mcm9tX2RhdGFfZnJhbWUoZCA9IGJyaWRvdmksIHZlcnRpY2VzID0gdnJob3ZpLCBkaXJlY3RlZCA9IFQpDQojIHBvc3RhdmxqYW5qZSBib2plIHZyaGEgKGFrbyBIYW5mYSBuYWR6aXJlICJibHVlIiwgaW5hxI1lICJncmF5IikNClYoZ3JhZikkY29sb3IgPC0gaWZlbHNlKFYoZ3JhZikkaGFuZmEgPT0gImRhIiwgImRlZXBza3libHVlMyIsICJhenVyZTMiKQ0KIyB2ZWxpxI1pbmEgb3puYWthIG5hIHZyaG92aW1hDQpWKGdyYWYpJGxhYmVsLmNleCA9IDAuOA0KIyBwb3N0YXZsamFuamUgYm9qZSBicmlkYSAoYWtvIDw1JSBpbW92aW5lLCBvbmRhIG5lbWEgYnJpZGEsIGFrbyBkbyAxMCUgb25kYSB6ZWxlbm8sIGFrbyBkbyAyMCUgb25kYSBuYXJhbsSNYXN0bywgYSBwcmVrbyBjcnZlbm8pDQpFKGdyYWYpJGNvbG9yIDwtIGlmZWxzZShFKGdyYWYpJGl6bG96ZW5vc3RfdmVsaWNpbmFfc2VrdG9yIDw9IDEwLCAiZGFya2dyZWVuIiwgaWZlbHNlKEUoZ3JhZikkaXpsb3plbm9zdF92ZWxpY2luYV9zZWt0b3IgPD0gMTUsInllbGxvdzMiLGlmZWxzZShFKGdyYWYpJGl6bG96ZW5vc3RfdmVsaWNpbmFfc2VrdG9yPD0yMCwiZGFya29yYW5nZSIsImRhcmtyZWQiKSkpDQoNCiMgc2xpa2EgbXJlxb5lIHBvdmV6YW5vc3RpDQoNCiMgcmF6bmUgZGVibGppbmUgYnJpZG92YQ0KI3Bsb3QoZ3JhZiwgdmVydGV4LnNpemUgPSBWKGdyYWYpJHZlbGljaW5hX2tydWdhLzIsIGVkZ2UuYXJyb3cuc2l6ZSA9IDAuNSwgbGF5b3V0PWxheW91dF9uaWNlbHkoZ3JhZiksIGVkZ2Uud2lkdGggPSBFKGdyYWYpJGl6bG96ZW5vc3RfdmVsaWNpbmFfc2VrdG9yLzgsIHZlcnRleC5sYWJlbC5jb2xvciA9ICJibGFjayIsIHZlcnRleC5mcmFtZS5jb2xvcj1OQSkNCiMgamVkbmFrZSBkZWJsamluZSBicmlkb3ZhDQpwbG90KGdyYWYsIHZlcnRleC5zaXplID0gMjUsIGVkZ2UuYXJyb3cuc2l6ZSA9IDAuNSwgbGF5b3V0PWxheW91dF9uaWNlbHkoZ3JhZiksIGVkZ2Uud2lkdGggPSAyLCB2ZXJ0ZXgubGFiZWwuY29sb3IgPSAiYmxhY2siLCB2ZXJ0ZXguZnJhbWUuY29sb3I9TkEpDQojIGxlZ2VuZGENCmxlZ2VuZCgidG9wbGVmdCIsIGxlZ2VuZD1jKCI8NSIsIjw1OzEwXSIsIjwxMDsxNV0iLCI8MTU7MjBdIiwiPjIwIiksIGZpbGw9Yygid2hpdGUiLCAiZGFya2dyZWVuIiwieWVsbG93MyIsImRhcmtvcmFuZ2UiLCJkYXJrcmVkIiksIHRpdGxlID0gIk96bmFrZSBib2phIHN0cmVsaWNhIFxuICh1ICUgdWt1cG5lIGltb3ZpbmUgc2VrdG9yYSkiLCBjZXg9MC44LCBidHk9Im4iKQ0KIyBicmlzYW5qZSBwcml2cmVtZW5paCB0YWJsaWNhDQpybSh6YWRuamlfZGF0dW0sYnJfZGFuYSxwb20xLHBvbTIscG9tMyxwb200LHBvbSxicmlkb3ZpLHZyaG92aSxncmFmLGZpbmFuY2lqc2tpX3JhY3VuaSkNCg0KYGBgDQoNCiMjIyA2LjMuIFNoaW55IGFwbGlrYWNpamENCg0KS2FkYSBzdSBwb2RhY2kgdSB0aWR5IGZvcm1hdHUsIG9uZGEgamUgbW9ndcSHZSBuYXByYXZpdGkgc2xqZWRlxId1IGFwbGlrYWNpanUgemEgYW5hbGl6dSBrcmV0YW5qYSB1IHN1c3RhdnUuDQoNCj4gZm9sZGVyICoqU2hpbnkgYmlsYW5jYSoqDQoNCiFbXShzaGlueV9iaWxhbmNhX3NsaWthLlBORykNCg0KIyMgNy4gQW5hbGl6YSBpIGtvbXVuaWthY2lqYSByZXp1bHRhdGENCg0KIyMjIDcuMS4gUGxvdGx5DQoNCk92byBqZSBwcmltamVyIEdhbnR0LWdyYWZpa29uYSBrb2ppIHN0ZSB2aWRqZWxpIHByb8WhbGkgdGplZGFuIHNhIHZyZW1lbnNraW0gcGxhbm9tIGFrdGl2bm9zdGkgb2tvIHByaXByZW1lIDQuIGJyb2phIE1ha3JvcHJ1ZGVuY2lqYWxub2cgc2tlbmVyYSByaXppa2EuDQoNCj4gc2tyaXB0YSAqKmdhbnR0X3NrZW5lcjQuUioqDQoNCiFbXShHYW50X3NrZW5lci5QTkcpDQoNCiMjIyA3LjIuIEdhcG1pbmRlciBwcmltamVyDQoNCkhhbnMgUm9zbGluZyBqZSBqZWRubyBvZCBuYWpwb3puYXRpamloIGltZW5hIHUgc3RhdGlzdGnEjWtpbSBrcnVnb3ZpbWEgaSB2ZWxpa2kgcG9wdWxhcml6YXRvciAiZGF0YSBzY2llbmNlYSIsIG5qZWdvdiBbVEVEIHRhbGtdKGh0dHBzOi8vd3d3LnRlZC5jb20vdGFsa3MvaGFuc19yb3NsaW5nX3RoZV9iZXN0X3N0YXRzX3lvdV92ZV9ldmVyX3NlZW4/bGFuZ3VhZ2U9aHIpIGplIGplZGFuIG9kIG5hamdsZWRhbmlqaWggaWthZGEgKHZlbGlrYSBwcmVwb3J1a2EgZGEgZ2EgcG9nbGVkYXRlKS4NCg0KPiBza3JpcHRhICoqZ2FwbWluZGVyIHByaW1qZXIuUioqDQoNCiFbXShHYXBtaW5kZXIuUE5HKQ0KDQojIyMgNy4zLiBTaGlueSBtcmXFvmUgT2VOQi1hDQoNCj4gZm9sZGVyICoqSlZJX0NvbnRhZ2lvbioqDQoNCiFbXShDb250YWdpb24uUE5HKQ0KDQojIyMgNy40LiBNYXBhIEVVDQoNClZybG8gamVkbm9zdGF2bm8gc2UgbW/FvmUgbmFwcmF2aXRpIGkgbWFwYSBFVSBwbyB6ZW1samFtYS4gTnByLCBwcmlrYXogZGVmaW5pY2lqZSByZWdpamEga29qZSBwcmlrYXp1amVtbyB1IHNrZW5lcnUuDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGdyaWQpDQpsaWJyYXJ5KHJ3b3JsZG1hcCkNCmxpYnJhcnkoZXVyb3N0YXQpDQpsaWJyYXJ5KGx1YnJpZGF0ZSkNCg0KIyBHZXQgdGhlIHdvcmxkIG1hcA0Kd29ybGRNYXAgPC0gZ2V0TWFwKCkNCg0KIyBNZW1iZXIgU3RhdGVzIG9mIHRoZSBFdXJvcGVhbiBVbmlvbg0KcmVnID0gZGF0YS5mcmFtZShyZWZfYXJlYT1jKCJBVCIsIkJFIiwiQkciLCJIUiIsIkNZIiwiQ1oiLCJESyIsIkVFIiwiRkkiLCJGUiIsIkRFIiwiR1IiLCJIVSIsIklFIiwiSVQiLCJMViIsIkxUIiwiTFUiLCJNVCIsIk5MIiwiUEwiLCJQVCIsIlJPIiwiU0siLCJTSSIsIkVTIiwiU0UiLCJHQiIpLGNvdW50cnk9YygiQXVzdHJpYSIsIkJlbGdpdW0iLCJCdWxnYXJpYSIsIkNyb2F0aWEiLCJDeXBydXMiLCJDemVjaCBSZXAuIiwiRGVubWFyayIsIkVzdG9uaWEiLCJGaW5sYW5kIiwiRnJhbmNlIiwiR2VybWFueSIsIkdyZWVjZSIsIkh1bmdhcnkiLCJJcmVsYW5kIiwiSXRhbHkiLCJMYXR2aWEiLCJMaXRodWFuaWEiLCJMdXhlbWJvdXJnIiwiTWFsdGEiLCJOZXRoZXJsYW5kcyIsIlBvbGFuZCIsIlBvcnR1Z2FsIiwiUm9tYW5pYSIsIlNsb3Zha2lhIiwiU2xvdmVuaWEiLCJTcGFpbiIsIlN3ZWRlbiIsIlVuaXRlZCBLaW5nZG9tIikscmVnaWphPWMoIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJDRUUiLCJIUiIsIk90aGVyIEVVIiwiQ0VFIiwiT3RoZXIgRVUiLCJDRUUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIsIkNFRSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJDRUUiLCJDRUUiLCJPdGhlciBFVSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJDRUUiLCJPdGhlciBFVSIsIkNFRSIsIkNFRSIsIkNFRSIsIk90aGVyIEVVIiwiT3RoZXIgRVUiLCJPdGhlciBFVSIpKQ0KDQojIFNlbGVjdCBvbmx5IHRoZSBpbmRleCBvZiBzdGF0ZXMgbWVtYmVyIG9mIHRoZSBFLlUuDQppbmRFVSA8LSB3aGljaCh3b3JsZE1hcCROQU1FICVpbiUgcmVnJGNvdW50cnkpDQoNCiMgRXh0cmFjdCBsb25naXR1ZGUgYW5kIGxhdGl0dWRlIGJvcmRlcidzIGNvb3JkaW5hdGVzIG9mIG1lbWJlcnMgc3RhdGVzIG9mIEUuVS4gDQpldXJvcGVDb29yZHMgPC0gbGFwcGx5KGluZEVVLCBmdW5jdGlvbihpKXsNCiAgZGYgPC0gZGF0YS5mcmFtZSh3b3JsZE1hcEBwb2x5Z29uc1tbaV1dQFBvbHlnb25zW1sxXV1AY29vcmRzKQ0KICBkZiRyZWdpb24gPWFzLmNoYXJhY3Rlcih3b3JsZE1hcCROQU1FW2ldKQ0KICBjb2xuYW1lcyhkZikgPC0gbGlzdCgibG9uZyIsICJsYXQiLCAicmVnaW9uIikNCiAgcmV0dXJuKGRmKQ0KfSkNCg0KZXVyb3BlQ29vcmRzIDwtIGRvLmNhbGwoInJiaW5kIiwgZXVyb3BlQ29vcmRzKQ0KDQojIDEuIE1hcGEgcmVnaWphICMjIyMNCmV1cm9wZWFuVW5pb25UYWJsZSA8LSBkYXRhLmZyYW1lKGNvdW50cnkgPSByZWckY291bnRyeSwgdmFsdWUgPSByZWckcmVnaWphKQ0KZXVyb3BlQ29vcmRzJHZhbHVlIDwtIGV1cm9wZWFuVW5pb25UYWJsZSR2YWx1ZVttYXRjaChldXJvcGVDb29yZHMkcmVnaW9uLGV1cm9wZWFuVW5pb25UYWJsZSRjb3VudHJ5KV0NCg0KIyBQbG90IHRoZSBtYXANClAgPC0gZ2dwbG90KCkgKyBnZW9tX3BvbHlnb24oZGF0YSA9IGV1cm9wZUNvb3JkcywgYWVzKHggPSBsb25nLCB5ID0gbGF0LCBncm91cCA9IHJlZ2lvbiwgZmlsbCA9IHZhbHVlKSwgY29sb3VyID0gImJsYWNrIiwgc2l6ZSA9IDAuMSkgKyBjb29yZF9tYXAoeGxpbSA9IGMoLTEzLCAzNSksICB5bGltID0gYygzMiwgNzEpKQ0KUCA8LSBQICsgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lID0gIlJlZ2lqYSIsIG5hLnZhbHVlID0gImdyZXk1MCIpDQpQIDwtIFAgKyB0aGVtZSgjcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBOQSksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2xpbmUoY29sb3VyID0gTkEpLA0KICAjcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG91ciA9IE5BKSwNCiAgYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksDQogIGF4aXMudGV4dC55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksDQogIGF4aXMudGlja3MueSA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgI3JlY3QgPSBlbGVtZW50X2JsYW5rKCksDQogIHBsb3QubWFyZ2luID0gdW5pdCgwICogYygtMS41LCAtMS41LCAtMS41LCAtMS41KSwgImxpbmVzIikpDQpQDQoNClAgPC0gUCArIHNjYWxlX2ZpbGxfZ3JhZGllbnQobmFtZSA9ICJHcm93dGggUmF0ZSIsIGxvdyA9ICIjRkYwMDAwRkYiLCBoaWdoID0gIiNGRkZGMDBGRiIsIG5hLnZhbHVlID0gImdyZXk1MCIpDQoNCg0KYGBgDQoNCg0KDQoNCkplZG5ha28gamVkbm9zdGF2bm8gc2UgbW/FvmUgbmFwcmF2aXRpIGkga29udGludWlyYW5hIG1hcGEga29qYSBucHIuIHByaWthenVqZSBrdW11bGF0aXZuaSByYXN0IEJEUC1hIG9kIDIwMTAuIHBvIEVVIHplbWxqYW1hLg0KDQpgYGB7cn0NCnBvbSA8LSBnZXRfZXVyb3N0YXQoaWQ9Im5hbXFfMTBfZ2RwIikgJT4lIGZpbHRlcihuYV9pdGVtPT0iQjFHUSIgJiBzX2Fkaj09Ik5TQSIgJiB1bml0PT0iQ0xWMTBfTU5BQyIpICU+JSBzZWxlY3QodGltZSxnZW8sYmRwPXZhbHVlcykgJT4lIGFycmFuZ2UodGltZSkgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgZ3JvdXBfYnkoZ2VvKSAlPiUgbXV0YXRlKGJkcF95ID0gKGJkcCArIGxhZyhiZHAsMSkrIGxhZyhiZHAsMikgKyBsYWcoYmRwLDMpKSkgJT4lIGZpbHRlcih0aW1lPj0iMjAwNy0xMC0wMSIpICU+JSBtdXRhdGUoZGF0dW0gPSBtYWtlX2RhdGUoaWZlbHNlKG1vbnRoKHRpbWUpPj0xMCx5ZWFyKHRpbWUpKzEseWVhcih0aW1lKSksaWZlbHNlKG1vbnRoKHRpbWUpPj0xMCwxLG1vbnRoKHRpbWUpKzMpLDEpIC0gMSkgJT4lIHNlbGVjdChkYXR1bSxyZWZfYXJlYT1nZW8sYmRwX3kpICU+JSBuYS5vbWl0KCkgJT4lIHVuZ3JvdXAoKQ0KYmF6YSA8LSBwb20gJT4lIGZpbHRlcihkYXR1bT09IjIwMTAtMTItMzEiKSAlPiUgc2VsZWN0KHJlZl9hcmVhLGJhemE9YmRwX3kpDQpkZWx0YV9iZHAgPC0gbGVmdF9qb2luKHBvbSxiYXphLGJ5PWMoInJlZl9hcmVhIikpICU+JSBtdXRhdGUoaW5kZWtzPWJkcF95L2JhemEqMTAwKSAlPiUgZmlsdGVyKGRhdHVtPT0iMjAxOS0wOS0zMCIpICU+JSBsZWZ0X2pvaW4ocmVnLGJ5PSJyZWZfYXJlYSIpICU+JSBuYS5vbWl0KCkNCg0KZXVyb3BlYW5VbmlvblRhYmxlIDwtIGRhdGEuZnJhbWUoY291bnRyeSA9IGRlbHRhX2JkcCRjb3VudHJ5LCB2YWx1ZSA9IGRlbHRhX2JkcCRpbmRla3MpDQpldXJvcGVDb29yZHMkdmFsdWUgPC0gZXVyb3BlYW5VbmlvblRhYmxlJHZhbHVlW21hdGNoKGV1cm9wZUNvb3JkcyRyZWdpb24sZXVyb3BlYW5VbmlvblRhYmxlJGNvdW50cnkpXQ0KDQojIFBsb3QgdGhlIG1hcA0KUCA8LSBnZ3Bsb3QoKSArIGdlb21fcG9seWdvbihkYXRhID0gZXVyb3BlQ29vcmRzLCBhZXMoeCA9IGxvbmcsIHkgPSBsYXQsIGdyb3VwID0gcmVnaW9uLCBmaWxsID0gdmFsdWUpLCBjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMC4xKSArIGNvb3JkX21hcCh4bGltID0gYygtMTMsIDM1KSwgIHlsaW0gPSBjKDMyLCA3MSkpDQpQIDwtIFAgKyBzY2FsZV9maWxsX2dyYWRpZW50KG5hbWUgPSAiS3VtdWxhdGl2bmkgcmFzdCBCRFAtYSBvZCAyMDEwLiIsIGxvdyA9ICJyZWQiLCBoaWdoID0gImdyZWVuIiwgbmEudmFsdWUgPSAiZ3JleTUwIikNClAgPC0gUCArIHRoZW1lKCNwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG91ciA9IE5BKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfbGluZShjb2xvdXIgPSBOQSksDQogICNwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3VyID0gTkEpLA0KICBheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGlja3MueCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgYXhpcy50aWNrcy55ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLA0KICAjcmVjdCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgcGxvdC5tYXJnaW4gPSB1bml0KDAgKiBjKC0xLjUsIC0xLjUsIC0xLjUsIC0xLjUpLCAibGluZXMiKSkNClANCiMgYnJpc2FuamUgcHJpdnJlbWVuaWggdGFibGljYQ0Kcm0od29ybGRNYXAscmVnLGluZEVVLGV1cm9wZUNvb3JkcyxldXJvcGVhblVuaW9uVGFibGUsUCxwb20sYmF6YSxkZWx0YV9iZHApDQoNCmBgYA0KDQojIyMgNy41LiBXb3JkIGNsb3VkIHJpamXEjWkga29qZSBzdSBzZSBuYWrEjWXFocSHZSBrb3Jpc3RpbGUgdSAzLiBicm9qdSBza2VuZXJhDQoNCj4gc2tyaXB0YSAqKndvcmRfY2xvdWQuUioqDQoNCiFbXSh3b3JkX2Nsb3VkLnBuZykNCg0KIyMgOC4gU2xqZWRlxIdpIGtvcmFjaQ0KDQpEbyBzYWRhIG5pamUgYmlsbyBwdW5vIGdvdm9yYSBvICppbi1ob3VzZSogcG9kYWNpbWEuIFRvIGplIGpvxaEgKndvcmsgaW4gcHJvZ3Jlc3MqLiBBa28gbmVrb2dhIHphbmltYSwgb3Zha28gaXpnbGVkYSBbc3RydWt0dXJhIHNrbGFkacWhdGEgcG9kYXRha2FdKGh0dHBzOi8vbW0udHQvMTM4MDIzNzU3OD90PUx0R1pLeldDZ0QpLiBQcmkgxI1lbXUgc3Zha2kgb2QgbmF2ZWRlbmloIMSNdm9yb3ZhIGplIGplZG5hIHZyc3RhIGl6bm9zYSBrb2ppIHNlIHBvaHJhbmp1amUgdSBiYXppIGltYSBzdm9qYSBwcmF2aWxhLiBUYWogZ29yZGlqc2tpIMSNdm9yIMSHZW1vIG1vcmF0aSByYXNwZXRsamF0aSBpIHByaXByZW1pdGkgcG9kYXRrZSAoKipvZHJhZGl0aSBvbmloIDgwJSBwb3NsYSoqKSB0YWtvIGRhIG1vxb5lbW8gcHJpc3R1cGl0aSBhbmFsaXppIG5hIGt2YWxpdGV0YW4gbmHEjWluLg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHJlYWR4bCkNCg0KIyBGdW5rY2lqYSB6YSBrb3BpcmFuamUgdSBleGNlbCAjIyMjDQpza29waXJhaiA8LSBmdW5jdGlvbih4LHJvdy5uYW1lcz1GQUxTRSxjb2wubmFtZXM9VFJVRSwuLi4pIHsNCiAgd3JpdGUudGFibGUoeCwiY2xpcGJvYXJkIixzZXA9Ilx0Iixyb3cubmFtZXM9cm93Lm5hbWVzLGNvbC5uYW1lcz1jb2wubmFtZXMsLi4uKQ0KfQ0KDQpsb2FkKCJmaW5wb2RhY2kuUmRhIikNCg0KIyAwLiBQb3BpcyBvYnJhemFjYSwgaXp2amXFoXRhamEsIHJlZGFrYSBpIHN0dXBhY2EgIyMjIw0KI3BvcGlzIDwtIGZpbnBvZGFjaSAlPiUgc2VsZWN0KHNla3RvcixpenZqZXN0YWosb2JyYXphYyxvem5ha2Ffb2JyYXNjYSxvem5ha2FfcmV0a2EscmVkYWssc3R1cGFjLHN0dXBhY19uYXppdikgJT4lIGRpc3RpbmN0KCkNCg0KIyAxLiBPc2lndXJhbmphIC0gYmlsYW5jYSAjIyMjDQpvc19iaWxhbmNhIDwtIGZpbnBvZGFjaSAlPiUgZmlsdGVyKGl6dmplc3RhaiAlaW4lIGMoIlRJRE8iLCJUSURSRSIsIlRJRE8tUkUiKSAmIG96bmFrYV9vYnJhc2NhPT0iU3RhbmRhcmRubyIgJiBvYnJhemFjICVpbiUgYygiQmlsYW5jYSIsIklGUCIpICYgc3R1cGFjX25heml2ICVpbiUgYygiVElETyAtIEJpbGFuY2EgLSBUZWt1xIdhIGdvZGluYSAtIMW9aXZvdCIsIlRJRE8gLSBCaWxhbmNhIC0gVGVrdcSHYSBnb2RpbmEgLSBOZcW+aXZvdCAiLCJUSURSRSAtIEJpbGFuY2EgLSBUZWt1xIdhIGdvZGluYSAtIMW9aXZvdCIsIlRJRFJFIC0gQmlsYW5jYSAtIFRla3XEh2EgZ29kaW5hIC0gTmXFvml2b3QgIiwiVElETy1SRSAtIElGUCAtIFRla3XEh2EgZ29kaW5hIC0gTmXFvml2b3QgIiwiVElETy1SRSAtIElGUCAtIFRla3XEh2EgZ29kaW5hIC0gxb1pdm90IikpICU+JSB1bml0ZSgib2JyYXphYyIsaXp2amVzdGFqLG9icmF6YWMsc2VwPSItIikgJT4lIHVuaXRlKCJyZWRhayIsb3puYWthX3JldGthLHJlZGFrLHNlcD0iLiIpICU+JSBzZWxlY3QoZGF0dW0sdnJzdGE9c3R1cGFjLHN1Ympla3Qsb2JyYXphYyxyZWRhayxpem5vcykgJT4lIG11dGF0ZSh2cnN0YT1zdHJfdHJpbSh2cnN0YSkscmVkYWs9c3RyX3RyaW0ocmVkYWspKQ0KIyB1dm96IHJhemluYSBpeiBleGNlbGENCnJhemluZSA8LSByZWFkX2V4Y2VsKCJNYXBpcmFuamUgb2JyYXphY2EgLSBvc2lndXJhbmphLnhsc3giLHNoZWV0ID0gInphX2l6dm96X2JpbGFuY2EiKQ0Kb3NfYmlsYW5jYSA8LSBmdWxsX2pvaW4ob3NfYmlsYW5jYSxyYXppbmUsYnk9Yygib2JyYXphYyIsInJlZGFrIikpICU+JSBuYS5vbWl0KCkNCg0KIyBTdHJ1a3R1cmEgaW1vdmluZQ0KcG9tIDwtIG9zX2JpbGFuY2EgJT4lIGdyb3VwX2J5KGRhdHVtLHJhemluYTIpICU+JSBmaWx0ZXIoZGF0dW0+PSIyMDExLTA5LTMwIiAmIHJhemluYTE9PSJJbW92aW5hIikgJT4lIHN1bW1hcmlzZShpem5vcz1zdW0oaXpub3MsbmEucm09VCkvMTAwMDAwMDAwMCkNCmdncGxvdChwb20sYWVzKHg9ZGF0dW0seT1pem5vcyxmaWxsPXJhemluYTIpKSArIGdlb21fYXJlYSgpICsgZ2d0aXRsZSgiSW1vdmluYSIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIpICsgbGFicyh4PSIiLHk9Im1scmQuIEhSSyIpDQojIFN0cnVrdHVyYSB1bGFnYW5qYQ0KcG9tIDwtIG9zX2JpbGFuY2EgJT4lIGdyb3VwX2J5KGRhdHVtLHJhemluYTMpICU+JSBmaWx0ZXIoZGF0dW0+PSIyMDExLTA5LTMwIiAmIHJhemluYTI9PSJVbGFnYW5qYSIpICU+JSBzdW1tYXJpc2UoaXpub3M9c3VtKGl6bm9zLG5hLnJtPVQpLzEwMDAwMDAwMDApDQpnZ3Bsb3QocG9tLGFlcyh4PWRhdHVtLHk9aXpub3MsZmlsbD1yYXppbmEzKSkgKyBnZW9tX2FyZWEoKSArIGdndGl0bGUoIlVsYWdhbmphIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKyB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAidG9wIikgKyBsYWJzKHg9IiIseT0ibWxyZC4gSFJLIikNCiMgU3RydWt0dXJhIG9idmV6YQ0KcG9tIDwtIG9zX2JpbGFuY2EgJT4lIGdyb3VwX2J5KGRhdHVtLHJhemluYTIpICU+JSBmaWx0ZXIoZGF0dW0+PSIyMDExLTA5LTMwIiAmIHJhemluYTE9PSJPYnZlemUiKSAlPiUgc3VtbWFyaXNlKGl6bm9zPXN1bShpem5vcyxuYS5ybT1UKS8xMDAwMDAwMDAwKQ0KZ2dwbG90KHBvbSxhZXMoeD1kYXR1bSx5PWl6bm9zLGZpbGw9cmF6aW5hMikpICsgZ2VvbV9hcmVhKCkgKyBnZ3RpdGxlKCJPYnZlemUiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArIGxhYnMoeD0iIix5PSJtbHJkLiBIUksiKQ0KIyBTdHJ1a3R1cmEgdGVobmnEjWtpaCBwcmnEjXV2YQ0KcG9tIDwtIG9zX2JpbGFuY2EgJT4lIGdyb3VwX2J5KGRhdHVtLHJhemluYTMpICU+JSBmaWx0ZXIoZGF0dW0+PSIyMDExLTA5LTMwIiAmIHJhemluYTI9PSJUZWhuacSNa2UgcHJpxI11dmUiKSAlPiUgc3VtbWFyaXNlKGl6bm9zPXN1bShpem5vcyxuYS5ybT1UKS8xMDAwMDAwMDAwKQ0KZ2dwbG90KHBvbSxhZXMoeD1kYXR1bSx5PWl6bm9zLGZpbGw9cmF6aW5hMykpICsgZ2VvbV9hcmVhKCkgKyBnZ3RpdGxlKCJUZWhuacSNa2UgcHJpxI11dmUiKSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiKSArIGxhYnMoeD0iIix5PSJtbHJkLiBIUksiKQ0KIyBicmlzYW5qZSBwcml2cmVtZW5paCB0YWJsaWNhDQpybShmaW5wb2RhY2ksb3NfYmlsYW5jYSxwb20scmF6aW5lKQ0KYGBgDQoNCg==